Use IO context for IO operations

This commit is contained in:
oSumAtrIX 2024-07-01 00:35:28 +02:00
parent e9d1c8fae0
commit 7f8f1ff589
No known key found for this signature in database
GPG Key ID: A9B3094ACDB604B4
3 changed files with 59 additions and 50 deletions

View File

@ -4,6 +4,8 @@ import app.revanced.api.configuration.repository.AnnouncementRepository.Attachme
import app.revanced.api.configuration.schema.APIAnnouncement
import app.revanced.api.configuration.schema.APIResponseAnnouncement
import app.revanced.api.configuration.schema.APIResponseAnnouncementId
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import kotlinx.datetime.*
import org.jetbrains.exposed.dao.IntEntity
import org.jetbrains.exposed.dao.IntEntityClass
@ -11,16 +13,18 @@ import org.jetbrains.exposed.dao.id.EntityID
import org.jetbrains.exposed.dao.id.IntIdTable
import org.jetbrains.exposed.sql.*
import org.jetbrains.exposed.sql.kotlin.datetime.datetime
import org.jetbrains.exposed.sql.transactions.transaction
import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction
internal class AnnouncementRepository(private val database: Database) {
init {
transaction {
SchemaUtils.create(AnnouncementTable, AttachmentTable)
runBlocking {
transaction {
SchemaUtils.create(AnnouncementTable, AttachmentTable)
}
}
}
fun all() = transaction {
suspend fun all() = transaction {
buildSet {
AnnouncementEntity.all().forEach { announcement ->
add(announcement.toApi())
@ -28,7 +32,7 @@ internal class AnnouncementRepository(private val database: Database) {
}
}
fun all(channel: String) = transaction {
suspend fun all(channel: String) = transaction {
buildSet {
AnnouncementEntity.find { AnnouncementTable.channel eq channel }.forEach { announcement ->
add(announcement.toApi())
@ -36,7 +40,7 @@ internal class AnnouncementRepository(private val database: Database) {
}
}
fun delete(id: Int) = transaction {
suspend fun delete(id: Int) = transaction {
val announcement = AnnouncementEntity.findById(id) ?: return@transaction
announcement.delete()
@ -44,27 +48,27 @@ internal class AnnouncementRepository(private val database: Database) {
// TODO: These are inefficient, but I'm not sure how to make them more efficient.
fun latest() = transaction {
suspend fun latest() = transaction {
AnnouncementEntity.all().maxByOrNull { it.createdAt }?.toApi()
}
fun latest(channel: String) = transaction {
suspend fun latest(channel: String) = transaction {
AnnouncementEntity.find { AnnouncementTable.channel eq channel }.maxByOrNull { it.createdAt }?.toApi()
}
fun latestId() = transaction {
suspend fun latestId() = transaction {
AnnouncementEntity.all().maxByOrNull { it.createdAt }?.id?.value?.let {
APIResponseAnnouncementId(it)
}
}
fun latestId(channel: String) = transaction {
suspend fun latestId(channel: String) = transaction {
AnnouncementEntity.find { AnnouncementTable.channel eq channel }.maxByOrNull { it.createdAt }?.id?.value?.let {
APIResponseAnnouncementId(it)
}
}
fun archive(
suspend fun archive(
id: Int,
archivedAt: LocalDateTime?,
) = transaction {
@ -73,13 +77,13 @@ internal class AnnouncementRepository(private val database: Database) {
}
}
fun unarchive(id: Int) = transaction {
suspend fun unarchive(id: Int) = transaction {
AnnouncementEntity.findById(id)?.apply {
archivedAt = null
}
}
fun new(new: APIAnnouncement) = transaction {
suspend fun new(new: APIAnnouncement) = transaction {
AnnouncementEntity.new announcement@{
author = new.author
title = new.title
@ -98,7 +102,7 @@ internal class AnnouncementRepository(private val database: Database) {
}
}
fun update(id: Int, new: APIAnnouncement) = transaction {
suspend fun update(id: Int, new: APIAnnouncement) = transaction {
AnnouncementEntity.findById(id)?.apply {
author = new.author
title = new.title
@ -117,7 +121,8 @@ internal class AnnouncementRepository(private val database: Database) {
}
}
private fun <T> transaction(block: Transaction.() -> T) = transaction(database, block)
private suspend fun <T> transaction(statement: Transaction.() -> T) =
newSuspendedTransaction(Dispatchers.IO, database, statement = statement)
private object AnnouncementTable : IntIdTable() {
val author = varchar("author", 32).nullable()

View File

@ -8,28 +8,28 @@ import kotlinx.datetime.LocalDateTime
internal class AnnouncementService(
private val announcementRepository: AnnouncementRepository,
) {
fun latestId(channel: String): APIResponseAnnouncementId? = announcementRepository.latestId(channel)
fun latestId(): APIResponseAnnouncementId? = announcementRepository.latestId()
suspend fun latestId(channel: String): APIResponseAnnouncementId? = announcementRepository.latestId(channel)
suspend fun latestId(): APIResponseAnnouncementId? = announcementRepository.latestId()
fun latest(channel: String) = announcementRepository.latest(channel)
fun latest() = announcementRepository.latest()
suspend fun latest(channel: String) = announcementRepository.latest(channel)
suspend fun latest() = announcementRepository.latest()
fun all(channel: String) = announcementRepository.all(channel)
fun all() = announcementRepository.all()
suspend fun all(channel: String) = announcementRepository.all(channel)
suspend fun all() = announcementRepository.all()
fun new(new: APIAnnouncement) {
suspend fun new(new: APIAnnouncement) {
announcementRepository.new(new)
}
fun archive(id: Int, archivedAt: LocalDateTime?) {
suspend fun archive(id: Int, archivedAt: LocalDateTime?) {
announcementRepository.archive(id, archivedAt)
}
fun unarchive(id: Int) {
suspend fun unarchive(id: Int) {
announcementRepository.unarchive(id)
}
fun update(id: Int, new: APIAnnouncement) {
suspend fun update(id: Int, new: APIAnnouncement) {
announcementRepository.update(id, new)
}
fun delete(id: Int) {
suspend fun delete(id: Int) {
announcementRepository.delete(id)
}
}

View File

@ -8,6 +8,8 @@ import app.revanced.library.PatchUtils
import app.revanced.patcher.PatchBundleLoader
import com.github.benmanes.caffeine.cache.Caffeine
import io.ktor.util.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.io.ByteArrayOutputStream
import java.net.URL
@ -73,36 +75,38 @@ internal class PatchesService(
configurationRepository.patches.repository,
)
return patchesListCache.get(patchesRelease.tag) {
val patchesDownloadUrl = patchesRelease.assets
.first(configurationRepository.patches.assetRegex).downloadUrl
return withContext(Dispatchers.IO) {
patchesListCache.get(patchesRelease.tag) {
val patchesDownloadUrl = patchesRelease.assets
.first(configurationRepository.patches.assetRegex).downloadUrl
val signatureDownloadUrl = patchesRelease.assets
.first(configurationRepository.patches.signatureAssetRegex).downloadUrl
val signatureDownloadUrl = patchesRelease.assets
.first(configurationRepository.patches.signatureAssetRegex).downloadUrl
val patchesFile = kotlin.io.path.createTempFile().toFile().apply {
outputStream().use { URL(patchesDownloadUrl).openStream().copyTo(it) }
}
val patchesFile = kotlin.io.path.createTempFile().toFile().apply {
outputStream().use { URL(patchesDownloadUrl).openStream().copyTo(it) }
}
val patches = if (
signatureService.verify(
patchesFile,
signatureDownloadUrl,
configurationRepository.patches.publicKeyFile,
)
) {
PatchBundleLoader.Jar(patchesFile)
} else {
// Use an empty set of patches if the signature is invalid.
emptySet()
}
val patches = if (
signatureService.verify(
patchesFile,
signatureDownloadUrl,
configurationRepository.patches.publicKeyFile,
)
) {
PatchBundleLoader.Jar(patchesFile)
} else {
// Use an empty set of patches if the signature is invalid.
emptySet()
}
patchesFile.delete()
patchesFile.delete()
ByteArrayOutputStream().use { stream ->
PatchUtils.Json.serialize(patches, outputStream = stream)
ByteArrayOutputStream().use { stream ->
PatchUtils.Json.serialize(patches, outputStream = stream)
stream.toByteArray()
stream.toByteArray()
}
}
}
}