Skip to content

Instantly share code, notes, and snippets.

View elizarov's full-sized avatar

Roman Elizarov elizarov

View GitHub Profile
// https://akarnokd.blogspot.ru/2017/09/rxjava-vs-kotlin-coroutines-quick-look.html
// Abstraction
import kotlinx.coroutines.experimental.*
suspend fun f1(i: Int): Int {
Thread.sleep(if (i != 2) 2000L else 200L)
return 1
}
suspend fun f2(i: Int): Int {
@elizarov
elizarov / Static.kt
Last active October 10, 2017 10:57
Kotlin approach to syntactically local static caching
import java.util.concurrent.atomic.AtomicReference
private val cache = object : ClassValue<AtomicReference<Any?>>() {
override fun computeValue(type: Class<*>) = AtomicReference<Any?>()
}
/**
* Caches the given expression statically.
*
* Use it like this:
@elizarov
elizarov / JT-44620.md
Created November 28, 2017 08:55
JT-44620.md

In markdown format empty line is not placed after the code block. For example:

this block

should be followed by an empty line in markdown mode, while it is not (it formats correctly in wiki mode)

@elizarov
elizarov / Debounce.kt
Last active August 26, 2019 00:19
Debounce
import kotlinx.coroutines.experimental.DefaultDispatcher
import kotlinx.coroutines.experimental.channels.ReceiveChannel
import kotlinx.coroutines.experimental.channels.consumeEach
import kotlinx.coroutines.experimental.channels.produce
import kotlinx.coroutines.experimental.delay
import kotlinx.coroutines.experimental.runBlocking
import kotlin.coroutines.experimental.CoroutineContext
fun <T> ReceiveChannel<T>.debounce(
wait: Long = 300,

Котлин революционизирует асинхронное программирование. В версии 1.1 в языке появились корутины -- это свежий, отличных от других языков подход к проблеме написания асинхронного кода. Мы посмотрим на этот механизм как сверху -- чем он отличается от традиционных подходов таких как callbacks, futures, и async/await, так и изнутри -- как всё это устроено. Более того, Котлин код можно компилировать под JVM и запускать бок-обок с Java кодом. Несмотря на то, что в Java не предполагается ничего для работы с асинхронностью на уровне языка, а все решения сосередоточены в библиотеках и подразумевают превращение любой нетривиальной асинхронной бизнес-логики в месиво замыкаканий и вызовов различных комбинаторов, корутины Котлина можно интегрировать и с асинхронных кодом на Java, что мы увидим на примерах.

@elizarov
elizarov / Main.kt
Created March 9, 2018 10:05
Kotlin Coroutines, a deeper look
// Inspired by http://akarnokd.blogspot.ru/2017/09/rxjava-vs-kotlin-coroutines-quick-look.html
// Requires Kotlin 1.2.30 or later
// Uses kotlinx.coroutines library
import kotlinx.coroutines.experimental.*
import kotlin.system.*
suspend fun f1(i: Int): Int {
println("f1 attempt $i")
delay(if (i != 3) 2000 else 200)
import kotlinx.coroutines.experimental.channels.*
import kotlinx.coroutines.experimental.*
class DownloadQueue {
private sealed class Msg {
class Request(val name: String) : Msg() {
val answer = CompletableDeferred<Unit>()
}
class Result(val name: String, val error: Throwable? = null) : Msg()
}
@elizarov
elizarov / DistinctInTimeWindow.kt
Created April 3, 2018 08:25
Channel operator to send distinct time elements in a specific time window
import kotlinx.coroutines.experimental.*
import kotlinx.coroutines.experimental.channels.*
import kotlinx.coroutines.experimental.selects.*
import java.util.concurrent.*
// operator
fun <T> ReceiveChannel<T>.distinctInTimeWindow(time: Long, unit: TimeUnit): ReceiveChannel<T> = produce {
require(time > 0)
consume {
val source = this@distinctInTimeWindow
@elizarov
elizarov / KT24481.kt
Created May 18, 2018 08:34
CompletableFuture exception wrapping
import java.util.concurrent.*
fun main(args: Array<String>) {
class DomainSpecificException : RuntimeException()
val cf1 = CompletableFuture<Int>()
val cf2 = CompletableFuture<Int>()
val res = cf1.thenCompose { cf2 }
cf1.whenComplete { _, err -> println("cf1: Completed with error = $err") }
import java.util.stream.Stream
abstract class NodeScaffold<THIS : NodeScaffold<THIS>> {
private val children: List<THIS>? = null
fun children(): Stream<THIS> {
return children!!.stream()
}