Skip to content

Commit

Permalink
Remove mutex from default sqlite
Browse files Browse the repository at this point in the history
Switched sqlite to use WAL journaling for concurrent read and writes
Added automatic query retry for rare cases of concurrent writes (rollback at the same time as heavy inserts)
  • Loading branch information
PotatoPresident committed May 27, 2024
1 parent abc1627 commit 0d6abc8
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 13 deletions.
2 changes: 1 addition & 1 deletion docs/parameters.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ An easy way to remember the difference between `before:1d` and `after:1d` is to
If you go back in time 1 day, do you want everything that happened `before` then or `after` then.
Usually you want `after`.

### Rollback Status
## Rollback Status
Key - `rolledback:`
Value - `true` or `false`
Negative Allowed - `No`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,7 @@ import com.github.quiltservertools.ledger.registry.ActionRegistry
import com.github.quiltservertools.ledger.utility.Negatable
import com.github.quiltservertools.ledger.utility.PlayerResult
import com.mojang.authlib.GameProfile
import java.time.Instant
import java.time.temporal.ChronoUnit
import java.util.*
import javax.sql.DataSource
import kotlinx.coroutines.delay
import kotlinx.coroutines.sync.Mutex
import net.minecraft.util.Identifier
import net.minecraft.util.WorldSavePath
import net.minecraft.util.math.BlockPos
Expand All @@ -30,7 +25,6 @@ import org.jetbrains.exposed.sql.Op
import org.jetbrains.exposed.sql.Query
import org.jetbrains.exposed.sql.SchemaUtils
import org.jetbrains.exposed.sql.SortOrder
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
import org.jetbrains.exposed.sql.SqlExpressionBuilder.inSubQuery
import org.jetbrains.exposed.sql.SqlExpressionBuilder.lessEq
import org.jetbrains.exposed.sql.SqlLogger
Expand All @@ -53,10 +47,19 @@ import org.jetbrains.exposed.sql.statements.expandArgs
import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction
import org.jetbrains.exposed.sql.transactions.transaction
import org.jetbrains.exposed.sql.update
import org.sqlite.SQLiteConfig
import org.sqlite.SQLiteDataSource
import java.time.Instant
import java.time.temporal.ChronoUnit
import java.util.*
import javax.sql.DataSource
import kotlin.io.path.pathString
import kotlin.math.ceil

const val MAX_QUERY_RETRIES = 10
const val MIN_RETRY_DELAY = 1000L
const val MAX_RETRY_DELAY = 300_000L

object DatabaseManager {

// These values are initialised late to allow the database to be created at server start,
Expand All @@ -66,8 +69,6 @@ object DatabaseManager {
get() = database.dialect.name

private val cache = DatabaseCacheService
private val dbMutex = Mutex()
private var enforceMutex = false

fun setup(dataSource: DataSource?) {
val source = dataSource ?: getDefaultDatasource()
Expand All @@ -76,8 +77,9 @@ object DatabaseManager {

private fun getDefaultDatasource(): DataSource {
val dbFilepath = Ledger.server.getSavePath(WorldSavePath.ROOT).resolve("ledger.sqlite").pathString
enforceMutex = true
return SQLiteDataSource().apply {
return SQLiteDataSource(SQLiteConfig().apply {
setJournalMode(SQLiteConfig.JournalMode.WAL)
}).apply {
url = "jdbc:sqlite:$dbFilepath"
}
}
Expand Down Expand Up @@ -354,12 +356,15 @@ object DatabaseManager {
}

private suspend fun <T : Any?> execute(body: suspend Transaction.() -> T): T {
if (enforceMutex) dbMutex.lock()
while (Ledger.server.overworld?.savingDisabled != false) {
delay(timeMillis = 1000)
}

return newSuspendedTransaction(db = database) {
repetitionAttempts = MAX_QUERY_RETRIES
minRepetitionDelay = MIN_RETRY_DELAY
maxRepetitionDelay = MAX_RETRY_DELAY

if (Ledger.config[DatabaseSpec.logSQL]) {
addLogger(object : SqlLogger {
override fun log(context: StatementContext, transaction: Transaction) {
Expand All @@ -368,7 +373,7 @@ object DatabaseManager {
})
}
body(this)
}.also { if (enforceMutex) dbMutex.unlock() }
}
}

suspend fun purgeActions(params: ActionSearchParams) {
Expand Down

0 comments on commit 0d6abc8

Please sign in to comment.