Skip to content

Commit

Permalink
Refactor rebuildCountryLeaderboard
Browse files Browse the repository at this point in the history
  • Loading branch information
ljdelight committed Jan 12, 2024
1 parent 3882d48 commit a8d1280
Showing 1 changed file with 111 additions and 63 deletions.
174 changes: 111 additions & 63 deletions app/org/maproulette/jobs/SchedulerActor.scala
Original file line number Diff line number Diff line change
Expand Up @@ -486,76 +486,124 @@ class SchedulerActor @Inject() (
val start = System.currentTimeMillis
logger.info(s"Scheduled Task '$action': Starting run")

db.withConnection { implicit c =>
// Clear TABLEs
SQL("DELETE FROM user_leaderboard WHERE country_code IS NOT NULL").executeUpdate()
SQL("DELETE FROM user_top_challenges WHERE country_code IS NOT NULL").executeUpdate()

val countryCodeMap = boundingBoxFinder.boundingBoxforAll()
for ((countryCode, boundingBox) <- countryCodeMap) {
SQL(
LeaderboardHelper.rebuildChallengesLeaderboardSQLCountry(
SchedulerActor.ONE_MONTH,
countryCode,
boundingBox,
config
)
).executeUpdate()
SQL(
LeaderboardHelper.rebuildChallengesLeaderboardSQLCountry(
SchedulerActor.THREE_MONTHS,
countryCode,
boundingBox,
config
)
).executeUpdate()
SQL(
LeaderboardHelper.rebuildChallengesLeaderboardSQLCountry(
SchedulerActor.SIX_MONTHS,
countryCode,
boundingBox,
config
)
).executeUpdate()
SQL(
LeaderboardHelper.rebuildChallengesLeaderboardSQLCountry(
SchedulerActor.TWELVE_MONTHS,
countryCode,
boundingBox,
config
)
).executeUpdate()
def deleteAndUpdateCountryLeaderboardForTimePeriod(
monthDuration: Int,
countryCode: String,
boundingBox: String
): Unit = {
logger.info(
s"Scheduled Task '$action': updating user_leaderboard monthDuration=$monthDuration countryCode=$countryCode"
)
db.withConnection { implicit c =>
// Delete the existing entries for the country and time period
SQL(
LeaderboardHelper.rebuildChallengesLeaderboardSQLCountry(
SchedulerActor.ALL_TIME,
countryCode,
boundingBox,
config
)
).executeUpdate()
s"DELETE FROM user_leaderboard WHERE country_code = {countryCode} AND month_duration = {monthDuration}"
).on(Symbol("countryCode") -> countryCode, Symbol("monthDuration") -> monthDuration)
.executeUpdate()
// Insert the new entries for the country and time period
SQL(
LeaderboardHelper.rebuildTopChallengesSQLCountry(
SchedulerActor.TWELVE_MONTHS,
countryCode,
boundingBox,
config
)
).executeUpdate()
SQL(
LeaderboardHelper.rebuildTopChallengesSQLCountry(
SchedulerActor.ALL_TIME,
countryCode,
boundingBox,
config
)
LeaderboardHelper
.rebuildChallengesLeaderboardSQLCountry(monthDuration, countryCode, boundingBox, config)
).executeUpdate()
}

val totalTime = System.currentTimeMillis - start
logger.info(
s"Scheduled Task '$action': Finished run. Time spent: ${String.format("%1d", totalTime)}ms"
s"Scheduled Task '$action': finished updating user_leaderboard monthDuration=$monthDuration countryCode=$countryCode"
)
}

val monthDurations = List(
SchedulerActor.ONE_MONTH,
SchedulerActor.THREE_MONTHS,
SchedulerActor.SIX_MONTHS,
SchedulerActor.TWELVE_MONTHS,
SchedulerActor.ALL_TIME
)

// Essential: The loop order prioritizes availability. The 'monthDurations' outer loop begins with shorter durations
// (1-3 months), ensuring quicker access to these results before moving to longer spans like "all time".
monthDurations.foreach(monthDuration => {
val countryCodeMap = boundingBoxFinder.boundingBoxforAll()
for ((countryCode, boundingBox) <- countryCodeMap) {
try {
deleteAndUpdateCountryLeaderboardForTimePeriod(monthDuration, countryCode, boundingBox)
} catch {
// If an exception occurs, log it and continue to the next country
case e: Exception =>
logger.error(
s"Failed to update user_leaderboard monthDuration=$monthDuration countryCode=$countryCode",
e
)
}
}
})

db.withConnection { implicit c =>
val countryCodeMap = boundingBoxFinder.boundingBoxforAll()
for ((countryCode, boundingBox) <- countryCodeMap) {
try {
logger.info(
s"Scheduled Task '$action': updating user_top_challenges monthDuration=12 countryCode=$countryCode"
)
// Delete the existing entries for the country and time period
SQL(
"DELETE FROM user_top_challenges WHERE country_code = {countryCode} AND month_duration = {monthDuration}"
).on(
Symbol("countryCode") -> countryCode,
Symbol("monthDuration") -> 12
)
.executeUpdate()

SQL(
LeaderboardHelper.rebuildTopChallengesSQLCountry(
SchedulerActor.TWELVE_MONTHS,
countryCode,
boundingBox,
config
)
).executeUpdate()
} catch {
case e: Exception =>
logger.error(
s"Error updating user_top_challenges for countryCode=$countryCode monthDuration=12",
e
)
}

try {
logger.info(
s"Scheduled Task '$action': updating user_top_challenges monthDuration=-1 countryCode=$countryCode"
)
// Delete the existing entries for the country and time period
SQL(
"DELETE FROM user_top_challenges WHERE country_code = {countryCode} AND month_duration = {monthDuration}"
).on(
Symbol("countryCode") -> countryCode,
Symbol("monthDuration") -> -1
)
.executeUpdate()

SQL(
LeaderboardHelper.rebuildTopChallengesSQLCountry(
SchedulerActor.ALL_TIME,
countryCode,
boundingBox,
config
)
).executeUpdate()
} catch {
case e: Exception =>
logger.error(
s"Error updating user_top_challenges for countryCode=$countryCode monthDuration=-1",
e
)
}
}
}

val totalTime = System.currentTimeMillis - start
logger.info(
s"Scheduled Task '$action': Finished run. Time spent: ${String.format("%1d", totalTime)}ms"
)
}

def sendImmediateNotificationEmails(action: String) = {
Expand Down

0 comments on commit a8d1280

Please sign in to comment.