Skip to content

Commit

Permalink
PIA-1900: Ping just one meta endpoint per region
Browse files Browse the repository at this point in the history
  • Loading branch information
kp-juan-docal committed Jun 5, 2024
1 parent cd83c79 commit 95f6034
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 76 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,29 +40,23 @@ internal actual class PingPerformer : CoroutineScope {
// endregion

actual fun pingEndpoints(
endpoints: Map<String, List<String>>,
callback: (result: Map<String, List<Pair<String, Long>>>) -> Unit
endpoints: Map<String, String>,
callback: (result: Map<String, Long>) -> Unit
) {
async {
val syncResult =
Collections.synchronizedMap(mutableMapOf<String, List<Pair<String, Long>>>())
val syncResult = Collections.synchronizedMap(mutableMapOf<String, Long>())
val requests: MutableList<Job> = mutableListOf()
for ((region, endpointsInRegion) in endpoints) {
val syncRegionEndpointsResults =
Collections.synchronizedList(mutableListOf<Pair<String, Long>>())
endpointsInRegion.forEach {
requests.add(async(Dispatchers.IO) {
var error: Error? = null
var latency = measureTimeMillis {
error = ping(it)
}
latency = error?.let {
REGIONS_PING_TIMEOUT.toLong()
} ?: latency
syncRegionEndpointsResults.add(Pair(it, latency))
syncResult[region] = syncRegionEndpointsResults
})
}
for ((region, endpointInRegion) in endpoints) {
requests.add(async(Dispatchers.IO) {
var error: Error?
var latency = measureTimeMillis {
error = ping(endpointInRegion)
}
latency = error?.let {
REGIONS_PING_TIMEOUT.toLong()
} ?: latency
syncResult[region] = latency
})
}
requests.joinAll()
launch(Dispatchers.Main) { callback(syncResult) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -259,12 +259,10 @@ public data class RegionJsonFallback(
* Data class defining the response object for a ping request. @see `fun pingRequests(...)`.
*
* @param region `String`.
* @param endpoint `String`.
* @param latency `String`.
*/
public data class RegionLowerLatencyInformation(
val region: String,
val endpoint: String,
val latency: Long
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,11 @@ package com.privateinternetaccess.regions.internals
internal expect class PingPerformer() {

/**
* @param endpoints Map<String, List<String>>. Key: Region. List<String>: Endpoints within the
* region.
* @param callback Map<String, List<Pair<String, Long>>>. Key: Region.
* List<Pair<String, Long>>>: Endpoints and latencies within the region.
* @param endpoints Map<String, String>. Key: Region. String: Endpoint to ping in the region.
* @param callback Map<String, Long>. Key: Region. Value: Latency.
*/
fun pingEndpoints(
endpoints: Map<String, List<String>>,
callback: (result: Map<String, List<Pair<String, Long>>>) -> Unit
endpoints: Map<String, String>,
callback: (result: Map<String, Long>) -> Unit
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -520,61 +520,36 @@ public class Regions internal constructor(
regionsResponse: VpnRegionsResponse,
callback: (response: List<RegionLowerLatencyInformation>) -> Unit
) {
val endpointsToPing = mutableMapOf<String, List<String>>()
val lowerLatencies = mutableListOf<RegionLowerLatencyInformation>()
val endpointsToPing = mutableMapOf<String, String>()
val latencies = mutableListOf<RegionLowerLatencyInformation>()

val allKnownEndpointsDetails = flattenEndpointsInformation(regionsResponse)
for ((region, regionEndpointInformation) in allKnownEndpointsDetails) {
val regionEndpoints = mutableListOf<String>()
regionEndpointInformation.forEach {
regionEndpoints.add(it.endpoint)
}
endpointsToPing[region] = regionEndpoints
endpointsToPing[region] = regionEndpointInformation.endpoint
}

pingPerformer.pingEndpoints(endpointsToPing) { latencyResults ->
for ((region, results) in latencyResults) {
if (results.isEmpty()) {
continue
}

results.minByOrNull { it.second }?.let { minEndpointLatency ->
allKnownEndpointsDetails[region]?.let { allKnownEndpointsDetails ->
allKnownEndpointsDetails.firstOrNull {
it.endpoint == minEndpointLatency.first
}?.let { minEndpointLatencyDetails ->
lowerLatencies.add(RegionLowerLatencyInformation(
minEndpointLatencyDetails.region,
minEndpointLatencyDetails.endpoint,
minEndpointLatency.second
))
}
}
}
for ((region, latency) in latencyResults) {
latencies.add(RegionLowerLatencyInformation(region, latency))
}
callback(lowerLatencies)
callback(latencies)
}
}

private fun flattenEndpointsInformation(
response: VpnRegionsResponse
): Map<String, List<RegionEndpointInformation>> {
val result = mutableMapOf<String, MutableList<RegionEndpointInformation>>()
): Map<String, RegionEndpointInformation> {
val result = mutableMapOf<String, RegionEndpointInformation>()
response.regions.forEach { region ->
region.servers[RegionsProtocol.META.protocol]?.forEach { regionServerProtocol ->
if (result[region.id] == null) {
result[region.id] = mutableListOf()
}
result[region.id]?.add(
RegionEndpointInformation(
region = region.id,
name = region.name,
iso = region.country,
dns = region.dns,
protocol = RegionsProtocol.META.protocol,
endpoint = regionServerProtocol.ip,
portForwarding = region.portForward
)
region.servers[RegionsProtocol.META.protocol]?.firstOrNull()?.let {
result[region.id] = RegionEndpointInformation(
region = region.id,
name = region.name,
iso = region.country,
dns = region.dns,
protocol = RegionsProtocol.META.protocol,
endpoint = it.ip,
portForwarding = region.portForward
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ internal actual class PingPerformer {
}

actual fun pingEndpoints(
endpoints: Map<String, List<String>>,
callback: (result: Map<String, List<Pair<String, Long>>>) -> Unit
endpoints: Map<String, String>,
callback: (result: Map<String, Long>) -> Unit
) {
val result = mutableMapOf<String, List<Pair<String, Long>>>()
val result = mutableMapOf<String, Long>()
callback(result)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ internal actual class PingPerformer {
}

actual fun pingEndpoints(
endpoints: Map<String, List<String>>,
callback: (result: Map<String, List<Pair<String, Long>>>) -> Unit
endpoints: Map<String, String>,
callback: (result: Map<String, Long>) -> Unit
) {
val result = mutableMapOf<String, List<Pair<String, Long>>>()
val result = mutableMapOf<String, Long>()
callback(result)
}
}

0 comments on commit 95f6034

Please sign in to comment.