Skip to content

Conversation

@aanorbel
Copy link
Member

@aanorbel aanorbel commented Oct 6, 2025

  • Implement dynamic GeoIP database updates by fetching the latest MMDB files from a GitHub repository
  • Perform daily version checks to avoid unnecessary downloads
  • Download new versions when available and clean up old database files to save space
  • Integrate the downloaded path into engine preferences for use in network tests

@aanorbel aanorbel marked this pull request as draft October 6, 2025 10:41
val ip: String?,
val asn: String?,
val countryCode: String?,
val geoIpdb: String?,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to get the geoIpDb from the engine?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To determine which version of geoIPDB the engine is currently working with.

@aanorbel aanorbel force-pushed the feat/dynamic-geoipdb branch 2 times, most recently from af697b7 to eef3dbc Compare October 28, 2025 16:11
@aanorbel aanorbel force-pushed the feat/dynamic-geoipdb branch from eef3dbc to b5322c8 Compare November 4, 2025 13:22
@aanorbel aanorbel requested a review from sdsantos November 5, 2025 08:20
@aanorbel aanorbel changed the title chore: draft for using geoipdb from path feat: dynamic geoip db support Nov 5, 2025
@aanorbel aanorbel marked this pull request as ready for review November 5, 2025 08:23
Copy link
Contributor

@sdsantos sdsantos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some other issues:
a) We're not cleaning old version of the geoIp database after we download an update
b) GeoIP databases will count for storage usaged, but they are not cleared when the clean storage (maybe this is what we want, but just wanted to make sure)
c) The fetch is running on app start, and therefore on any instrumented test we have. It should be disabled for most tests I imagine.

Comment on lines 29 to 30
const val GEOIP_DB_VERSION_DEFAULT: String = "20250801"
const val GEOIP_DB_REPO: String = "aanorbel/oomplt-mmdb"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These constants could be private.

private fun buildGeoIpDbUrl(version: String): String =
"https://github.com/${GEOIP_DB_REPO}/releases/download/$version/$version-ip2country_as.mmdb"

private fun normalize(tag: String): Int = tag.removePrefix("v").trim().toInt()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're trusting that the tag will always be an Int, otherwise the app crashes. I think we should fail silently instead if that's the case.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And why do we need to remove the prefix, if we're the ones in control of the repository? Right now, if there's a v in the tag there maybe be some bugs, for example, will the v also be present here:
"https://github.com/${GEOIP_DB_REPO}/releases/download/$version/$version-ip2country_as.mmdb"?

return Success(null)
} else {
val url = buildGeoIpDbUrl(latestVersion)
val target = "$cacheDir/$latestVersion.mmdb"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the cacheDir the place we really want for these files? Is some systems, cache directories can be deleted periodically.

@aanorbel aanorbel force-pushed the feat/dynamic-geoipdb branch from b1d98df to 305a640 Compare November 12, 2025 13:57
) {
companion object {
private const val GEOIP_DB_VERSION_DEFAULT: String = "20250801"
private const val GEOIP_DB_REPO: String = "aanorbel/oomplt-mmdb"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now can we move this to a proper repository under the OONI account?

Comment on lines 43 to 47
val currentTimeMillis = Clock.System.now().toEpochMilliseconds()
val oneDayInMillis = 24 * 60 * 60 * 1000L
val timeSinceLastCheck = currentTimeMillis - lastCheckMillis

if (timeSinceLastCheck < oneDayInMillis) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can take advantage of kotlin.time.Duration to make this more clear:

if (Clock.System.now() - Instant.fromEpochMilliseconds(lastCheckMillis) < 1.days) {
    
}


suspend operator fun invoke(): Result<Path?, MkException> {
// Check if we've already checked today
val lastCheckMillis = preferencesRepository.getValueByKey(SettingsKey.MMDB_LAST_CHECK).first() as? Long
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that we have the check, we can prevent this check from happening in instrumented tests, like I have here with disableRefreshArticles():

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants