New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added lazy mountable extensions #3187
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm so sorry @sksamuel, my comment has been pending on this PR for 2 + weeks.. 🤦♂️
this.value = value | ||
} | ||
|
||
fun get() = value |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this not be protected from incorrect access during initialisation? It can only be safely accessed from TestScope
? That actually depends on how the underlying Extension
initialises it, right?
This would work for my use-case, but the API is rather unsafe.
In the PR with the original use-case here there is LazyMaterialized
with suspend fun get()
so it can only be accessed from suspend TestScope.() -> Unit
. If it's access before it needs to be somehow in a suspend
context and will get loaded lazily then. If it's accessed after clear/close
is called (on afterSpec
or similar) then it'll throw an IllegalStateException
.
Should we have a similarly "safer" API? I.e. the example here Kafka
also involves some heavy I/O, blocking code both on start
and close
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, short-answer: yes this works.
Long-answer: should we try to make the API safer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree the API isn't great, but I don't know how we can limit it to test scope, or even if we care about that, as long as it supports suspension.
Like you might want to initialize in a before spec listener. That's a suspendable context.
Let me think more on this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok I have followed your guidelines and it is much clearer now.
A LazyMountableExtension
returns a LazyMaterialized
which has a SAM.
interface LazyMaterialized<MATERIALIZED> {
suspend fun get(): MATERIALIZED
}
Once get is invoked, the implementation can initialize if required.
Here is the example from the tests:
object : LazyMaterialized<String> {
var state: String? = null
override suspend fun get(): String {
delay(1)
if (state == null) state = "ready"
return state ?: error("Must be initialized")
}
}
Thank you for looking into this @sksamuel 🙏 |
Would something as simple as this suffice for your needs @nomisRev