How to call a polymorphic function which depends on multiple Typeclasses in Kotlin/Arrow - monad-transformers

I've created a function which is polymorphic in the Monad it needs to use, instead it depends on the typeclass instances that exists for this Monad. It looks like this:
fun <M> M.logic(...): Kind<M, String>
where M: MonadReader<M, Dependency>,
M: Effect<M> =
fx.monad() {
val dependency = ask().bind()
val response = effect { ...using dependency here... }.bind()
response
}
I'm using the MonadReader to get a dependency, and I'm using Effect, well, for effects. Now I assumed, that all I need is to use some Monad Transformers to get to this constellation of a Monad "at the end of the world" (i.e. in main()). Something like ReaderT<ForIO, Dependency, Unit>.
However, I can't seem to create a suitable M (or any context) to call this method on. How can I call this method on an exact monad that has the necessary typeclass instances?

This is the code snippet you're after:
fun <M, F> M.logic(): Kind<F, String>
where M: MonadReader<F, String>,
M: Async<F> =
fx.monad {
val dependency = ask().bind()
val response = effect { dependency }.bind()
response
}
object Transformer:
Async<KleisliPartialOf<ForIO, String>> by ReaderT.async(IO.effect()),
KleisliMonadReader<ForIO, String> by ReaderT.monadReader(IO.monad())
Note that Async is what you're after, not the poorly named Effect. And you need two generics, one for the composition and another for the content.
Transformer.run {
logic()
}
The Async instance for Reader was added on January 2020, and will be available on the next release, either 0.10.5 or 0.11.0: https://github.com/arrow-kt/arrow/commit/6aaae6998de612eb0eec948697f1c477649230be

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

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 define facade for a method that emits events in ScalaJS

I'm writing scalajs facade for pouchdb
code : https://gist.github.com/chandu0101/62013de47bf5ee4d2412
how to define facade for API name changes which emits events and return a cancel method ..
Defining Scala.js facade types is all about giving static types to a JavaScript API. Usually the documentation of the JavaScript does mention types, which can therefore be translated into a formal definition pretty easily.
In this case, the changes methods returns an EventEmitter, which is the first thing you need. Let us define this type, and in particular its on method:
class EventEmitter extends js.Object {
def on(event: String, listener: js.Function): this.type = js.native
...
}
We have to be very imprecise for the type of listener, unfortunately, because the actual type will very much depend on the event string, and the particular uses of that emitter. In general, we cannot predict anything at this point.
The documentation of EventEmitter doesn't mention a cancel() method, which is a bit weird since apparently that method can be called on the emitter returned by changes. So we'll define a subtype for the particular emitter returned by changes:
trait ChangesEventEmitter extends EventEmitter {
def cancel(): Unit = js.native
}
We can also take advantage of this specialized trait to enable a more precise type of listener for particular events. In this case, let us do it for the change event:
object ChangesEventEmitter {
implicit class ChangesEventEmitterEvents(
val self: ChangesEventEmitter) extends AnyVal {
def onChange(listener: js.Function1[js.Dynamic, Any]): self.type =
self.on("change", listener)
}
}
Finally, you need a type for the options parameter of the db.changes method. The type itself is usually a trait with many immutable fields:
trait DBChangesOptions extends js.Object {
val include_docs: js.UndefOr[Boolean] = js.native
val limit: js.UndefOr[Int] = js.native
...
}
To construct an instance of such a type, you may either go with an apply method in the companion object with default arguments (see this SO question), or you can create a Builder-like class for it.
And now, we can finally declare the changes method itself:
def changes(options: DBChangesOptions = ???): ChangesEventEmitter = js.native

Is there any way to clean up the following generic method using any of the new C# 4 features?

I've just modified a method for handling my DDD commands (previously it had no return type):
public static CommandResult<TReturn> Execute<TCommand, TReturn>(TCommand command)
where TCommand : IDomainCommand
{
var handler = IoCFactory.GetInstance<ICommandHandler<TCommand, TReturn>>();
return handler.Handle(command);
}
The method is fine, and does what I want it to do, however using it creates some fugly code:
CommandResult<Customer> result =
DomainCommands.Execute<CustomerCreateCommand, Customer>
(
new CustomerCreateCommand(message)
);
Before I added the Customer return type TReturn, it was nice and tidy and the method could infer the types from its usage. However that's no longer possible.
Is there any way using any new C# features that I could rewrite the above to make it tidier, i.e. using Func, Action, Expression, etc? I'm probably expecting the impossible, but I'm getting fed up of writing so much code to just call a single method that used to be very simple.
One option to reduce it slightly is to have a static generic type for the type parameter that can't be inferred, allowing you to have a generic method with just one type parameter that can be inferred:
public static class DomainCommands<TReturn>
{
public static CommandResult<TReturn> Execute<TCommand>(TCommand command)
where TCommand : IDomainCommand
{
var handler = IoCFactory.GetInstance<ICommandHandler<TCommand, TReturn>>();
return handler.Handle(command);
}
}
Then:
var result = DomainCommands<Customer>.Execute(new CustomerCreateCommand(msg));
It's not much nicer, but it's slightly better. Of course, if the domain command type itself could be generic, that might help - so CustomerCreateCommand would implement IDomainCommand<Customer> for example. If you still needed a nongeneric IDomainCommand, you could make IDomainCommand<T> derive from IDomainCommand.

Resources