-
Notifications
You must be signed in to change notification settings - Fork 337
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Remove source code sanitizer, switch to tapir, use sttp as client, ad…
…d throttling, deduplicate sent reports
- Loading branch information
Showing
25 changed files
with
155 additions
and
946 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
88 changes: 25 additions & 63 deletions
88
metals/src/main/scala/scala/meta/internal/telemetry/TelemetryClient.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,84 +1,46 @@ | ||
package scala.meta.internal.telemetry | ||
|
||
import scala.concurrent.ExecutionContext | ||
import scala.concurrent.Future | ||
import scala.util.Random | ||
import scala.util.Success | ||
import sttp.client3._ | ||
|
||
import scala.meta.internal.metals.LoggerAccess | ||
import scala.meta.internal.metals.TelemetryLevel | ||
import scala.meta.internal.telemetry | ||
|
||
import requests.Response | ||
import sttp.tapir.client.sttp.SttpClientInterpreter | ||
import sttp.model.Uri | ||
import com.google.common.util.concurrent.RateLimiter | ||
|
||
object TelemetryClient { | ||
|
||
case class Config(serverHost: String) | ||
case class Config(serverHost: Uri) | ||
object Config { | ||
// private final val DefaultTelemetryEndpoint = | ||
// "https://scala3.westeurope.cloudapp.azure.com/telemetry" | ||
private final val DefaultTelemetryEndpoint = "http://localhost:8081" | ||
private final val DefaultTelemetryEndpoint = uri"http://localhost:8081" | ||
val default: Config = Config(DefaultTelemetryEndpoint) | ||
} | ||
|
||
private class TelemetryRequest[In]( | ||
endpoint: telemetry.FireAndForgetEndpoint[In], | ||
logger: LoggerAccess, | ||
)(implicit config: Config, ec: ExecutionContext) { | ||
private val endpointURL = s"${config.serverHost}${endpoint.uri}" | ||
private val requester = requests.send(endpoint.method) | ||
println(s"TelemetryClient: sending $endpointURL") | ||
private val interpreter = SttpClientInterpreter() | ||
|
||
def apply(data: In): Unit = { | ||
val json = endpoint.encodeInput(data) | ||
val response = execute(json) | ||
acknowledgeResponse(response) | ||
} | ||
|
||
private def execute( | ||
data: String, | ||
retries: Int = 3, | ||
backoffMillis: Int = 100, | ||
): Future[Response] = Future { | ||
requester( | ||
url = endpointURL, | ||
data = data, | ||
keepAlive = false, | ||
check = false, | ||
) | ||
}.recoverWith { | ||
case _: requests.TimeoutException | _: requests.UnknownHostException | ||
if retries > 0 => | ||
Thread.sleep(backoffMillis) | ||
execute(data, retries - 1, backoffMillis + Random.nextInt(1000)) | ||
} | ||
|
||
private def acknowledgeResponse(response: Future[Response]): Unit = | ||
response.onComplete { | ||
case Success(value) if value.is2xx => | ||
case _ => | ||
logger.debug( | ||
s"${endpoint.method}:${endpoint.uri} should never result in error, got ${response}" | ||
) | ||
} | ||
} | ||
} | ||
|
||
private[meta] class TelemetryClient( | ||
telemetryLevel: () => TelemetryLevel, | ||
class TelemetryClient( | ||
config: TelemetryClient.Config = TelemetryClient.Config.default, | ||
logger: LoggerAccess = LoggerAccess.system, | ||
)(implicit ec: ExecutionContext) | ||
extends telemetry.TelemetryService { | ||
) { | ||
import TelemetryClient._ | ||
import telemetry.TelemetryService._ | ||
|
||
implicit private def clientConfig: Config = config | ||
|
||
private val sendErrorReport0 = | ||
new TelemetryRequest(sendErrorReportEndpoint, logger) | ||
|
||
def sendErrorReport(report: telemetry.ErrorReport): Unit = | ||
if (telemetryLevel().enabled) sendErrorReport0(report) | ||
|
||
val rateLimiter = RateLimiter.create(1.0 / 5.0) | ||
|
||
val backend = HttpClientFutureBackend() | ||
val sendReport: ErrorReport => Unit = report => { | ||
if (rateLimiter.tryAcquire()) { | ||
logger.debug("Sending telemetry report.") | ||
interpreter | ||
.toClient( | ||
TelemetryEndpoints.sendReport, | ||
baseUri = Some(config.serverHost), | ||
backend = backend, | ||
) | ||
.apply(report) | ||
} else logger.debug("Report was omitted, because of quota") | ||
() | ||
} | ||
} |
Oops, something went wrong.