samedi 12 mai 2018

Scala - try with resources

I continue to learn Scala, and I look for resource management. I would like to have the same approach as in Kotlin. I searched for quite a long time, until I found a video and an implementation https://gist.github.com/densh/75d2d3063571d89ee34e161b4a61c74a that helped me finding a way

I started from this code and I enhanced it to look like my previous post for Kotlin.
find this code in https://github.com/spointeau/scala-using-autoClose/blob/master/MainUsing.scala

I also did re-implement the .use{} that I generally use in Kotlin when I deal with only 1 or 2 resources max. The implementation was so simple by reusing the autoClose. You can find the code in the same github file.

test1
Close test2
May 13, 2018 1:04:27 AM arm$using$ $anonfun$apply$1
WARNING: Close Exception test2
Close test1
java.lang.Exception: Close Exception test1
at TestToClose.close(MainUsing.scala:166)
at arm$using$.$anonfun$apply$1(MainUsing.scala:119)
at arm$using$.$anonfun$apply$1$adapted(MainUsing.scala:117)
at scala.collection.immutable.List.foreach(List.scala:389)
at arm$using$.apply(MainUsing.scala:117)
at MainUsing$.delayedEndpoint$MainUsing$1(MainUsing.scala:177)
at MainUsing$delayedInit$body.apply(MainUsing.scala:173)
at scala.Function0.apply$mcV$sp(Function0.scala:34)
at scala.Function0.apply$mcV$sp$(Function0.scala:34)
at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
at scala.App.$anonfun$main$1$adapted(App.scala:76)
at scala.collection.immutable.List.foreach(List.scala:389)
at scala.App.main(App.scala:76)
at scala.App.main$(App.scala:74)
at MainUsing$.main(MainUsing.scala:173)
at MainUsing.main(MainUsing.scala)
test3
Close test3
test4
Close test4
java.lang.Exception: Close Exception test4
at TestToClose.close(MainUsing.scala:166)
at arm$using$.$anonfun$apply$1(MainUsing.scala:119)
at arm$using$.$anonfun$apply$1$adapted(MainUsing.scala:117)
at scala.collection.immutable.List.foreach(List.scala:389)
at arm$using$.apply(MainUsing.scala:117)
at arm$AutoCloseResource$.use$extension1(MainUsing.scala:152)
at arm$AutoCloseResource$.use$extension0(MainUsing.scala:150)
at MainUsing$.delayedEndpoint$MainUsing$1(MainUsing.scala:193)
at MainUsing$delayedInit$body.apply(MainUsing.scala:173)
at scala.Function0.apply$mcV$sp(Function0.scala:34)
at scala.Function0.apply$mcV$sp$(Function0.scala:34)
at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
at scala.App.$anonfun$main$1$adapted(App.scala:76)
at scala.collection.immutable.List.foreach(List.scala:389)
at scala.App.main(App.scala:76)
at scala.App.main$(App.scala:74)
at MainUsing$.main(MainUsing.scala:173)
at MainUsing.main(MainUsing.scala)

did it help you?

jeudi 10 mai 2018

kotlin - try with resources

This is a long time I did not post, no excuse, I decided to post my last attempt to close resources in Kotlin. In a earlier post, I wrote how much I found Kotlin to be refreshing.

I recently tried Scala and during my learning of Scala, I immediately wondered how to close properly the resource like the try-with-resources from Java. I was really hoping that it was built-in but it is not unfortunately.

Then I thought about Kotlin, which has now the .use {} pattern. However I know by experience that it can be cumbersome if we have multiple resources, ending with a lot of nested . use{ .use{ .use{} } }

Did you think how the kotlin .use{} or the java try-with-resources works if the close raises an exception? it just raises.

what if we don't want the close to raise?

In java, the best approach I have see is to wrap the resource as explained here https://stackoverflow.com/questions/6889697/close-resource-quietly-using-try-with-resources

basically to wrap the resource like
try(QuietResource qr = new QuietResource<>(new MyResource())){
    MyResource r = qr.get();
    r.read();
} catch (Exception e) {
    System.out.println("Exception: " + e.getMessage());
}

While we can use the same approach for kotlin and wrap the resource and apply the .use{} on this wrapper, I would like to avoid all the nested use{} when we have multiple resources.

Inspired by the "using" block proposed by one member of the JetBrains team
https://discuss.kotlinlang.org/t/kotlin-needs-try-with-resources/214

I started from there and improved it for the exception handling. I wanted to be able also to control if the close must raise or at least the exception must appear in the log.

IMO the standard behaviour must be kept to raise if the close raises an exception but we should be able to make it closing quietly without exception and log it to keep an eye on it. Of course, all resources must be closed even so some raised an exception.

My proposed code is

class UsingResourceHolder {

    data class Resource(val x: AutoCloseable, val canThrow: Boolean, val doLog: Boolean)

    internal val resources = LinkedList()
    var logger: Logger? = Logger.getLogger("global")

    fun <T : AutoCloseable> T.autoClose(canThrow:Boolean = true, log:Boolean = false): T {
        resources.addFirst(Resource(this, canThrow = canThrow, doLog = log))
        return this    }

    fun <T : AutoCloseable> T.autoCloseQuietly(log:Boolean = false): T {
        return this.autoClose(canThrow=false,log=log)
    }

}

fun <R> using(block: UsingResourceHolder.() -> R): R {
    val holder = UsingResourceHolder()

    var globalException: Throwable? = null    var exceptionOnClose: Throwable? = null
    try {
        return holder.block()
    }
    catch(t: Throwable) {
        globalException = t
        throw t
    }
    finally {
        holder.resources.forEach { r ->            try {
                r.x.close()
            }
            catch (e: Exception) {

                if( globalException == null ) {
                    if( r.canThrow ) {
                        if (exceptionOnClose == null) exceptionOnClose = e
                        else exceptionOnClose!!.addSuppressed(e)
                    }
                    else if(r.doLog) {
                        holder.logger?.warning(e.message)
                    }
                }
                else {
                    if( r.canThrow ) globalException!!.addSuppressed(e)
                }
            }
        }
        if (exceptionOnClose != null) throw exceptionOnClose!!
    }
}


and how to use it:



and the output is:
May 12, 2018 8:01:25 PM TryWithResourceKt using
WARNING: exception from ExceptionMaker.ex3
Exception in thread "main" java.lang.Exception: exception from ExceptionMaker.ex2
at ExceptionMaker.close(TryWithResource.kt:69)
at TryWithResourceKt.using(TryWithResource.kt:39)
at TryWithResourceKt.main(TryWithResource.kt:75)
Suppressed: java.lang.Exception: exception from ExceptionMaker.ex1
... 3 more

In case the using block is raising an exception, the exceptions from the close are then suppressed by this main exception:



Exception in thread "main" java.lang.Exception: Code failure
at TryWithResourceKt$main$1.invoke(TryWithResource.kt:81)
at TryWithResourceKt$main$1.invoke(TryWithResource.kt)
at TryWithResourceKt.using(TryWithResource.kt:30)
at TryWithResourceKt.main(TryWithResource.kt:75)
Suppressed: java.lang.Exception: exception from ExceptionMaker.ex2
at ExceptionMaker.close(TryWithResource.kt:69)
at TryWithResourceKt.using(TryWithResource.kt:39)
... 1 more
Suppressed: java.lang.Exception: exception from ExceptionMaker.ex1
at ExceptionMaker.close(TryWithResource.kt:69)
at TryWithResourceKt.using(TryWithResource.kt:39)
... 1 more

What do you think?


magic mouse 2 and Razer Destructor 2

Finally I found the ideal mouse pad, also working with my magic mouse 2: the Razer Destructor 2