Joshua Hansen
01/08/2024, 8:52 PMprivate val accumulators = mutableMapOf(
"foo" to 0,
"bar" to 0,
)
Then later on in an init block, I'm doing a heavy IO operation to count all the values. I'm walking a large file tree:
init {
MyScope(Dispatchers.IO).launch {
// Walk file tree and accumulate values in map
}
}
finally I have them declared in the class as delegates:
val foo by accumulators
val bar by accumulators
How can I ensure that the init
block runs before foo
and bar
are accessed? I'm using Swing, and when the UI loads, the user can click to display information. This operation inside init
can take a few seconds, and it's possible the user requests the information during accumulation. Is there some sort of locking mechanism I can use so that when the user requests the info, it will wait in the backgorund and then show on the UI?Joshua Hansen
01/08/2024, 8:55 PMuli
01/08/2024, 9:33 PMDeferred<Map<String,Int>>
would do the trick. But then you have to await the value which needs a suspend function.
As properties can not have supsend getters, you’d need to write a regular suspend fun:
private val accumulators : Deferred<Map<String,Int>>
init {
val completableDeferred = CompletableDeferred<Map<String,Int>>
accumulators = completableDeferred
val map = mutableMapOf(
"foo" to 0,
"bar" to 0,
)
MyScope(Dispatchers.IO).launch {
// Walk file tree and accumulate values in map
completableDeferred.compete(map)
}
}
suspend fun foo() = accumulators.await().get("foo")
uli
01/08/2024, 9:35 PMJoshua Hansen
01/08/2024, 9:45 PMfoo
and bar
are using a PropertyDelegateProvider which takes a suspend
lamda as its delegate getValue funtion, and inside that lambda is where I get the map's value, so it ends up being exactly what I need.Joshua Hansen
01/08/2024, 9:46 PMuli
01/08/2024, 9:48 PMJoshua Hansen
01/08/2024, 9:51 PMgetValue()
function.uli
01/08/2024, 9:52 PMJoshua Hansen
01/08/2024, 9:52 PMuli
01/08/2024, 9:53 PM