Skip to content

Commit

Permalink
Use built in Kotlin Dispatchers.IO for file access
Browse files Browse the repository at this point in the history
  • Loading branch information
PrinsINT committed Jun 14, 2024
1 parent dbd474f commit e57e2e7
Showing 1 changed file with 8 additions and 49 deletions.
57 changes: 8 additions & 49 deletions server/src/main/kotlin/org/ivdnt/galahad/FileBackedValue.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ package org.ivdnt.galahad

import com.fasterxml.jackson.core.type.TypeReference
import com.fasterxml.jackson.databind.ObjectMapper
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import org.apache.logging.log4j.kotlin.Logging
import java.io.*
import java.nio.ByteBuffer
Expand Down Expand Up @@ -60,21 +63,8 @@ open class FileBackedValue<T>(
// It was not set yet
return initValue
}

val channel = FileChannel.open(file.toPath(), StandardOpenOption.READ)
channel.use {
val lock = lockFile( channel, false )
lock.use {
val fileSize = channel.size().toInt()
val byteBuffer: ByteBuffer = ByteBuffer.allocate(fileSize)
channel.read(byteBuffer)
byteBuffer.flip()
val bytes: ByteArray = byteBuffer.array()
byteBuffer.clear()
return mapper.readValue( bytes, object : TypeReference<S>() {})
}
}

val bytes: ByteArray = runBlocking(Dispatchers.IO) { file.inputStream().use { it.readBytes() }}
return mapper.readValue(bytes, object : TypeReference<S>() {})
}

/**
Expand All @@ -88,41 +78,10 @@ open class FileBackedValue<T>(
if( !file.exists() ) {
file.createNewFile()
}

// Would love to do this atomically, but for now we won't
val oldValue = read<S>()

val channel = FileChannel.open(file.toPath(), StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING )
channel.use {
val lock = lockFile( channel, true )
lock.use {
val newValue = modification( oldValue )
val newValBytes = mapper.writeValueAsBytes( newValue )
logger.trace("will write $newValue")
val byteBuffer = ByteBuffer.wrap( newValBytes )
channel.write( byteBuffer )
}
}
val newValue = modification(oldValue)
val newValBytes = mapper.writeValueAsBytes(newValue)
runBlocking(Dispatchers.IO) { file.writeBytes(newValBytes)}
}

fun lockFile( channel: FileChannel, exclusive: Boolean ): FileLock? {
while (true) {
try {
return if( exclusive ) {
channel.lock()
} else {
channel.lock(0L, Long.MAX_VALUE, true)
}
} catch (ignored: OverlappingFileLockException) {
} catch (ignored: IOException) {
}
try {
logger.info("Tried to read access $file but it was locked. Will sleep for ${LOCK_SLEEP_TIME}ms now then retry.")
Thread.sleep(LOCK_SLEEP_TIME)
} catch (e: InterruptedException) {
e.printStackTrace()
}
}
}

}

0 comments on commit e57e2e7

Please sign in to comment.