com.lightningkite.lightningdb.InMemoryUnsafePersistentFieldCollection.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of server-core Show documentation
Show all versions of server-core Show documentation
A set of tools to fill in/replace what Ktor is lacking in.
The newest version!
package com.lightningkite.lightningdb
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.actor
import kotlinx.serialization.KSerializer
import kotlinx.serialization.StringFormat
import kotlinx.serialization.builtins.ListSerializer
import java.io.Closeable
import java.io.File
import java.nio.file.Files
import java.nio.file.StandardCopyOption
import java.util.*
/**
* An InMemoryFieldCollection with the added feature of loading data from a file at creation
* and writing the collection data into a file when closing.
*/
class InMemoryUnsafePersistentFieldCollection(
val encoding: StringFormat,
serializer: KSerializer,
val file: File
) : InMemoryFieldCollection(
data = Collections.synchronizedList(ArrayList()),
serializer = serializer
), Closeable{
private val scope = CoroutineScope(Dispatchers.IO)
@OptIn(ObsoleteCoroutinesApi::class)
val saveScope = scope.actor(start = CoroutineStart.LAZY) {
handleCollectionDump()
}
init {
data.addAll(
encoding.decodeFromString(
ListSerializer(serializer),
file.takeIf { it.exists() }?.readText() ?: "[]"
)
)
val shutdownHook = Thread {
handleCollectionDump()
}
Runtime.getRuntime().addShutdownHook(shutdownHook)
this.signals.add {
close()
}
}
override fun close() {
scope.launch {
saveScope.send(Unit)
}
}
fun handleCollectionDump() {
val temp = file.parentFile!!.resolve(file.name + ".saving")
temp.writeText(encoding.encodeToString(ListSerializer(serializer), data.toList()))
Files.move(temp.toPath(), file.toPath(), StandardCopyOption.ATOMIC_MOVE)
logger.debug("Saved $file")
}
}