Optaplanner: How to get solver instance in Quarkus - quarkus

I am using Quarkus optaplanner, so instead of using SolverFactory to build a solver, I us ethe Quarkus way to inject a solverManager then let it solve the problem:
val solverJob: SolverJob<SolarDesign, UUID> = solverManager.solve(problemId, problem)
But I want to still be able to addEventListener like:
solver.addEventListener(SolverEventListener<SolarDesign>() {
fun bestSolutionChanged(event: BestSolutionChangedEvent<MyProblem>) {
val solution = event.getNewBestSolution()
if (solution.score.isFeasible()) {
println("found new best solution")
println(solution)
}
}
})
Question is how do I get a solver instance in Quarkus optaplanner so I can use it to addEventListener? It does not seem to be doable from solverManager.
Thanks

Yes, that is possible with SolverManager and you don't need to obtain a Solver instance.
Use SolverManager.solverAndListen(problemId, problemFinder, bestSolutionConsumer). The third argument is a consumer where you can do whatever you want with each best solution that is found. It could look something like this in your case:
fun solve() {
val solverJob: SolverJob<SolarDesign, UUID> = solverManager
.solveAndListen(problemId, { problemId -> problem }, this::printSolution)
}
fun printSolution(solution: SolarDesign) {
if (solution.score.isFeasible()) {
println("found new best solution")
println(solution)
}
}
Find more details in this section about SolverManager.

The following example shows how to obtain a Solver instance in Quarkus. The SolverManager API does not cover this option so the alternative approach is to inject a SolverFactory, use it to build a Solver instance and manage its lifecycle yourself.
The example also shows how to get access to the Phase lifecycle. It can be useful for experiments during development. However, that's only possible through casting the solver instance to DefaultSolver, which is an internal API. There are no backward compatibility guarantees on the internal classes. They can significantly change in future minor releases and cause compilation errors if you use them in your code. Do not use it in production.
class MySolverResource(private val solverFactory: SolverFactory<SolarDesign>) {
fun solve(problemId : UUID) {
// WARNING: DefaultSolver is OptaPlanner's internal class.
// Backward compatibility is not guaranteed.
// Its usage is totally not recommended.
val solver: DefaultSolver<SolarDesign> = solverFactory.buildSolver() as DefaultSolver<SolarDesign>
solver.addPhaseLifecycleListener(object : PhaseLifecycleListenerAdapter<SolarDesign>() {
override fun stepEnded(stepScope: AbstractStepScope<SolarDesign>) {
printSolution(stepScope.createOrGetClonedSolution())
}
})
solver.solve(loadProblem(problemId))
}
fun printSolution(solution: SolarDesign) {}
}

Related

Springboot coroutine bean scope or local scope

I have a requirement, where we want to asynchronously handle some upstream request/payload via coroutine. I see that there are several ways to do this, but wondering which is the right approach -
Provide explicit spring service class that implements CoroutineScope
Autowire singleton scope-context backed by certain defined thread-pool dispatcher.
Define method local CoroutineScope object
Following on this question, I'm wondering whats the trade-off if we define method local scopes like below -
fun testSuspensions(count: Int) {
val launchTime = measureTimeMillis {
val parentJob = CoroutineScope(Dispatchers.IO).launch {
repeat(count) {
this.launch {
process() //Some lone running process
}
}
}
}
}
Alternative approach to autowire explicit scope object backed by custom dispatcher -
#KafkaListener(
topics = ["test_topic"],
concurrency = "1",
containerFactory = "someListenerContainerConfig"
)
private fun testKafkaListener(consumerRecord: ConsumerRecord<String, ByteArray>, ack: Acknowledgment) {
try {
this.coroutineScope.launch {
consumeRecordAsync(consumerRecord)
}
} finally {
ack.acknowledge()
}
}
suspend fun consumeRecordAsync(record: ConsumerRecord<String, ByteArray>) {
println("[${Thread.currentThread().name}] Starting to consume record - ${record.key()}")
val statusCode = initiateIO(record) // Add error-handling depending on kafka topic commit semantics.
// Chain any-other business logic (depending on status-code) as suspending functions.
consumeStatusCode(record.key(), statusCode)
}
suspend fun initiateIO(record: ConsumerRecord<String, ByteArray>): Int {
return withContext(Dispatchers.IO) { // Switch context to IO thread for http.
println("[${Thread.currentThread().name}] Executing network call - ${record.key()}")
delay(1000 * 2) // Simulate IO call
200 // Return status-code
}
}
suspend fun consumeStatusCode(recordKey: String, statusCode: Int) {
delay(1000 * 1) // Simulate work.
println("[${Thread.currentThread().name}] consumed record - $recordKey, status-code - $statusCode")
}
Autowiring bean as follows in some upstream config class -
#Bean(name = ["testScope"])
fun defineExtensionScope(): CoroutineScope {
val threadCount: Int = 4
return CoroutineScope(Executors.newFixedThreadPool(threadCount).asCoroutineDispatcher())
}
It depends on what your goal is. If you just want to avoid the thread-per-request model, you can use Spring's support for suspend functions in controllers instead (by using webflux), and that removes the need from even using an external scope at all:
suspend fun testSuspensions(count: Int) {
val execTime = measureTimeMillis {
coroutineScope {
repeat(count) {
launch {
process() // some long running process
}
}
}
}
// all child coroutines are done at this point
}
If you really want your method to return immediately and schedule coroutines that outlive it, you indeed need that extra scope.
Regarding option 1), making custom classes implement CoroutineScope is not encouraged anymore (as far as I understood). It's usually suggested to use composition instead (declare a scope as a property instead of implementing the interface by your own classes). So I would suggest your option 2.
I would say option 3) is out of the question, because there is no point in using CoroutineScope(Dispatchers.IO).launch { ... }. It's no better than using GlobalScope.launch(Dispatchers.IO) { ... } (it has the same pitfalls) - you can read about the pitfalls of GlobalScope in its documentation.
The main problem being that you run your coroutines outside structured concurrency (your running coroutines are not children of a parent job and may accumulate and hold resources if they are not well behaved and you forget about them). In general it's better to define a scope that is cancelled when you no longer need any of the coroutines that are run by it, so you can clean rogue coroutines.
That said, in some circumstances you do need to run coroutines "forever" (for the whole life of your application). In that case it's ok to use GlobalScope, or a custom application-wide scope if you need to customize things like the thread pool or exception handler. But in any case don't create a scope on the spot just to launch a coroutine without keeping a handle to it.
In your case, it seems you have no clear moment when you wouldn't care about the long running coroutines anymore, so you may be ok with the fact that your coroutines can live forever and are never cancelled. In that case, I would suggest a custom application-wide scope that you would wire in your components.

Redis transaction in Spring Boot + Kotlin

I am trying to execute a transaction on a Redis instance from within Spring Boot application written in Kotlin. I have followed the recommendation in Spring Doc on the best practice to achieve this.
I am struggling with the Kotlin implementation, however. Specifically, I don't know how to implement the Java generic interface with a generic method to make it work in the Kotlin code:
redisTemplate.execute(object : SessionCallback<List<String>> {
override fun <K : Any?, V : Any?> execute(operations: RedisOperations<K, V>): List<String>? {
operations.multi()
operations.opsForValue().set("key", "value")
return operations.exec()
}
})
The code above complains that the set method expects parameters with types K and V respectively but String is found instead.
Is there an elegant way how to inline the interface implementation in Kotlin without having to use unchecked casting or other convoluted approaches to make this work?
I think you're facing this problem due to poor interface definition for SessionCallback and the framework itself is doing unsafe casts themselves.
You see, if we take a look into the SessionCallback definition over here we can see that it looks as follows:
public interface SessionCallback<T> {
#Nullable
<K,V> T execute(RedisOperations<K,V> operations) throws DataAccessException
}
The generics K,V referring to the type of keys and values from your Redis are not parameters of the SessionCallback interface and that's why the kotlin compiler is having a hard time inferring the type of these: Because the execute function only takes a parameter of type SessionCallback<T> without passing the types of keys and values as parameters to that interface.
Your best-effort might be to provide a nice wrapper around that API using extension functions and inline generic types by doing some controlled unsafe casts.
Something like this might be enough:
inline fun <reified K : Any?, reified V: Any?, reified T> RedisTemplate<K, V>.execute(crossinline callback: (RedisOperations<K,V>) -> T?): T?{
val callback = object : SessionCallback<T> {
override fun <KK, VV> execute(operations: RedisOperations<KK,VV>) = callback(operations as RedisOperations<K, V>) as T?
}
return execute(callback)
}
Which then you can consume by doing:
fun doSomething(redisTemplate: RedisTemplate<String, String>) {
redisTemplate.execute { operations ->
operations.multi()
operations.opsForValue().set("key", "value")
operations.exec() as List<String>
}
}
And yes, you need to cast the .exec() result because nobody bothered using generics and returns a List<Object> as you can see on the official documentation

How to handle tap events for an interactive watch faces with androidx.wear?

What is the correct way of handling tap events with the new androidx.wear.watchface libraries? I was doing this with the now deprecated android.support:wearable libraries without any problem with Java (using onTapCommand). Now, everything seems to be quite different, especially since the documentation and examples seem to be available only in Kotlin. Also, I can't find any example which properly shows how the functions are used.
The documentation mentions setTapListener, TapListener. And then there are the functions onTap, onTapEvent and onTapCommand. This seems very confusing.
Could somebody put here a small example? Or point me to a working example on the internet?
Any help much appreciated!
Implementing this seemed to work for me
https://developer.android.com/reference/androidx/wear/watchface/WatchFace.TapListener
My code:
class WatchFaceRenderer(...): Renderer.CanvasRenderer(...), WatchFace.TapListener {
override fun onTapEvent(tapType: Int, tapEvent: TapEvent, complicationSlot: ComplicationSlot?) {
if (tapType == TapType.UP)
// do something
invalidate()
}
}
class Service : WatchFaceService() {
override suspend fun createWatchFace(
surfaceHolder: SurfaceHolder,
watchState: WatchState,
complicationSlotsManager: ComplicationSlotsManager,
currentUserStyleRepository: CurrentUserStyleRepository
): WatchFace {
val renderer = WatchFaceRenderer(
context = applicationContext,
surfaceHolder = surfaceHolder,
watchState = watchState,
currentUserStyleRepository = currentUserStyleRepository,
canvasType = CanvasType.SOFTWARE,
)
return WatchFace(WatchFaceType.ANALOG, renderer).setTapListener(renderer)
}
}

Is CoroutineScope(SupervisorJob()) runs in Main scope?

I was doing this code lab
https://developer.android.com/codelabs/android-room-with-a-view-kotlin#13
and having a question
class WordsApplication : Application() {
// No need to cancel this scope as it'll be torn down with the process
val applicationScope = CoroutineScope(SupervisorJob())
// Using by lazy so the database and the repository are only created when they're needed
// rather than when the application starts
val database by lazy { WordRoomDatabase.getDatabase(this, applicationScope) }
val repository by lazy { WordRepository(database.wordDao()) }
}
private class WordDatabaseCallback(
private val scope: CoroutineScope
) : RoomDatabase.Callback() {
override fun onCreate(db: SupportSQLiteDatabase) {
super.onCreate(db)
INSTANCE?.let { database ->
scope.launch {
var wordDao = database.wordDao()
// Delete all content here.
wordDao.deleteAll()
// Add sample words.
var word = Word("Hello")
wordDao.insert(word)
word = Word("World!")
wordDao.insert(word)
// TODO: Add your own words!
word = Word("TODO!")
wordDao.insert(word)
}
}
}
}
this is the code I found, as you can see, it is directly calling scope.launch(...)
my question is that:
isn't all the Room operations supposed to run in non-UI scope? Could someone help me to understand this? thanks so much!
Is CoroutineScope(SupervisorJob()) runs in Main scope?
No. By default CoroutineScope() uses Dispatchers.Default, as can be found in the documentation:
CoroutineScope() uses Dispatchers.Default for its coroutines.
isn't all the Room operations supposed to run in non-UI scope?
I'm not very familiar specifically with Room, but generally speaking it depends if the operation is suspending or blocking. You can run suspend functions from any dispatcher/thread. deleteAll() and insert() functions in the example are marked as suspend, therefore you can run them from both UI and non-UI threads.

how to selectively set a property using DEPENDENCY INJECTION in a grails service for unit testing

EDIT: Please let me be clear, I'm asking how to do this in Grails using Spring Dependency Injection, and NOT Grails' metaclass functionality or new().
I have a grails service that is for analyzing log files. Inside the service I use the current time for lots of things. For unit testing I have several example log files that I parse with this service. These have times in them obviously.
I want my service, DURING UNIT TESTING to think that the current time is no more than a few hours after the last logging statement in my example log files.
So, I'm willing to this:
class MyService {
def currentDate = { -> new Date() }
def doSomeStuff() {
// need to know when is "right now"
Date now = currentDate()
}
}
So, what I want to be able to do is have currentDate injected or set to be some other HARDCODED time, like
currentDate = { -> new Date(1308619647140) }
Is there not a way to do this with some mockWhatever method inside my unit test? This kind of stuff was super easy with Google Guice, but I have no idea how to do it in Spring.
It's pretty frustrating that when I Google "grails dependency injection" all I find are examples of
class SomeController {
// wow look how amazing this is, it's injected automatically!!
// isn't spring incredible OMG!
def myService
}
It feels like all that's showing me is that I don't have to type new ...()
Where do I tell it that when environment equals test, then do this:
currentDate = { -> new Date(1308619647140) }
Am I just stuck setting this property manually in my test??
I would prefer not to have to create a "timeService" because this seems silly considering I just want 1 tiny change.
Groovy is a dynamic language, and as such it allows you to do almost what you're asking for:
class MyServiceTests extends GrailsUnitTestCase {
def testDoSomeStuff() {
def service = new MyService()
service.currentDate = { -> new Date(1308619647140) }
// assert something on service.doSomeStuff()
}
}
Keep in mind this only modifies the service instance, not the class. If you need to modify the class you'll need to work with the metaClass. Take a look at this post by mrhaki.
Another option would be to make the current date a parameter to doSomeStuff(). That way you wouldn't need to modify your service instance.
Thanks for the help guys. The best solution I could come up with for using Spring DI in this case was to do the following in
resources.groovy
These are the two solutions I found:
1: If I want the timeNowService to be swapped for testing purposes everywhere:
import grails.util.GrailsUtil
// Place your Spring DSL code here
beans = {
if (GrailsUtil.environment == 'test') {
println ">>> test env"
timeNowService(TimeNowMockService)
} else {
println ">>> not test env"
timeNowService(TimeNowService)
}
}
2: I could do this if I only want this change to apply to this particular service:
import grails.util.GrailsUtil
// Place your Spring DSL code here
beans = {
if (GrailsUtil.environment == 'test') {
println ">>> test env"
time1(TimeNowMockService)
} else {
println ">>> not test env"
time1(TimeNowService)
}
myService(MyService) {
diTest = 'hello 2'
timeNowService = ref('time1')
}
}
In either case I would use the service by calling
timeNowService.now().
The one strange, and very frustrating thing to me was that I could not do this:
import grails.util.GrailsUtil
// Place your Spring DSL code here
beans = {
if (GrailsUtil.environment == 'test') {
println ">>> test env"
myService(MyService) {
timeNow = { -> new Date(1308486447140) }
}
} else {
println ">>> not test env"
myService(MyService) {
timeNow = { -> new Date() }
}
}
}
In fact, when I tried that I also had a dummy value in there, like dummy = 'hello 2' and then a default value of dummy = 'hello' in the myService class itself. And when I did this 3rd example with the dummy value set in there as well, it silently failed to set, apparently b/c timeNow blew something up in private.
I would be interested to know if anyone could explain why this fails.
Thanks for the help guys and sorry to be impatient...
Since Groovy is dynamic, you could just take away your currentDate() method from your service and replace it by one that suits your need. You can do this at runtime during the setup of your test.
Prior to having an instance of MyService instantiated, have the following code executed:
MyService.metaClass.currentDate << {-> new Date(1308619647140) }
This way, you can have a consistent behavior across all your tests.
However, if you prefer, you can override the instance method by a closure that does the same trick.
Let me know how it goes.
Vincent Giguère

Resources