Skip to content

Commit

Permalink
Schedule the automated backup on a specific time of the day
Browse files Browse the repository at this point in the history
  • Loading branch information
schroda committed Jul 11, 2023
1 parent 2ff8cef commit 6b2df86
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 19 deletions.
3 changes: 3 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@ twelvemonkeys-imageio-webp = { module = "com.twelvemonkeys.imageio:imageio-webp"
# Testing
mockk = "io.mockk:mockk:1.13.2"

# cron scheduler
cron4j = "it.sauronsoftware.cron4j:cron4j:2.2.5"

[plugins]
# Kotlin
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin"}
Expand Down
2 changes: 2 additions & 0 deletions server/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ dependencies {
implementation("com.graphql-java:graphql-java-extended-scalars:20.0")

testImplementation(libs.mockk)

implementation(libs.cron4j)
}

application {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ package suwayomi.tachidesk.manga.impl.backup.proto
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */

import eu.kanade.tachiyomi.source.model.UpdateStrategy
import it.sauronsoftware.cron4j.Scheduler
import it.sauronsoftware.cron4j.Task
import it.sauronsoftware.cron4j.TaskExecutionContext
import mu.KotlinLogging
import okio.buffer
import okio.gzip
Expand Down Expand Up @@ -41,48 +44,53 @@ import java.io.File
import java.io.InputStream
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Timer
import java.util.TimerTask
import java.util.concurrent.TimeUnit
import java.util.prefs.Preferences
import kotlin.time.Duration.Companion.days

object ProtoBackupExport : ProtoBackupBase() {
private val logger = KotlinLogging.logger { }
private val applicationDirs by DI.global.instance<ApplicationDirs>()
private var backupSchedulerJobId: String = ""
private const val lastAutomatedBackupKey = "lastAutomatedBackupKey"
private val preferences = Preferences.userNodeForPackage(ProtoBackupExport::class.java)

private val backupTimer = Timer()
private var currentAutomatedBackupTask: TimerTask? = null
private val scheduler = Scheduler()

fun scheduleAutomatedBackupTask() {
scheduler.deschedule(backupSchedulerJobId)

if (!serverConfig.automatedBackups) {
currentAutomatedBackupTask?.cancel()
return
}

val minInterval = 1.days
val interval = serverConfig.backupInterval.days
val backupInterval = interval.coerceAtLeast(minInterval).inWholeMilliseconds

val lastAutomatedBackup = preferences.getLong(lastAutomatedBackupKey, 0)
val initialDelay =
backupInterval - (System.currentTimeMillis() - lastAutomatedBackup) % backupInterval
if (!scheduler.isStarted) {
scheduler.start()
}

currentAutomatedBackupTask?.cancel()
currentAutomatedBackupTask = object : TimerTask() {
override fun run() {
val task = object : Task() {
override fun execute(context: TaskExecutionContext?) {
cleanupAutomatedBackups()
createAutomatedBackup()
preferences.putLong(lastAutomatedBackupKey, System.currentTimeMillis())
}
}

backupTimer.scheduleAtFixedRate(
currentAutomatedBackupTask,
initialDelay,
backupInterval
val (hour, minute) = serverConfig.backupTime.split(":").map { it.toInt() }
val backupHour = hour.coerceAtLeast(0).coerceAtMost(23)
val backupMinute = minute.coerceAtLeast(0).coerceAtMost(59)
val backupInterval = serverConfig.backupInterval.days.coerceAtLeast(1.days)

// trigger last backup in case the server wasn't running on the scheduled time
val lastAutomatedBackup = preferences.getLong(lastAutomatedBackupKey, System.currentTimeMillis())
val wasPreviousBackupTriggered = (System.currentTimeMillis() - lastAutomatedBackup) < backupInterval.inWholeMilliseconds
if (!wasPreviousBackupTriggered) {
scheduler.launch(task)
}

backupSchedulerJobId = scheduler.schedule(
"$backupMinute $backupHour */${backupInterval.inWholeDays} * *",
task
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class ServerConfig(getConfig: () -> Config, moduleName: String = MODULE_NAME) :

// backup
var backupPath: String by overridableConfig
var backupTime: String by overridableConfig
var backupInterval: Int by overridableConfig
var automatedBackups: Boolean by overridableConfig
var backupTTL: Int by overridableConfig
Expand Down
1 change: 1 addition & 0 deletions server/src/main/resources/server-reference.conf
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ server.systemTrayEnabled = true

# backup
server.backupPath = ""
server.backupTime = "00:00" # range: hour: 0-23, minute: 0-59 - default: "00:00" - time of day at which the automated backup should be triggered
server.backupInterval = 1 # time in days - range: 1 <= n < ∞ - default: 1 day - interval in which the server will automatically create a backup
server.automatedBackups = true
server.backupTTL = 14 # time in days - 0 to disable it - range: 1 <= n < ∞ - default: 14 days - how long backup files will be kept before they will get deleted
1 change: 1 addition & 0 deletions server/src/test/resources/server-reference.conf
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ server.electronPath = ""

# backup
server.backupPath = ""
server.backupTime = "00:00"
server.backupInterval = 1
server.automatedBackups = true
server.backupTTL = 14

0 comments on commit 6b2df86

Please sign in to comment.