Skip to content
This repository has been archived by the owner on Dec 21, 2023. It is now read-only.

Commit

Permalink
Examples and specs are updated to Kotlin 1.3 coroutines
Browse files Browse the repository at this point in the history
  • Loading branch information
elizarov committed Oct 18, 2018
1 parent e818483 commit 0904690
Show file tree
Hide file tree
Showing 49 changed files with 602 additions and 526 deletions.
8 changes: 5 additions & 3 deletions .idea/kotlin-coroutines.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions .idea/libraries/KotlinJavaRuntime.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 3 additions & 5 deletions README.md
Expand Up @@ -5,8 +5,8 @@ It is logically a part of [KEEP](https://github.com/Kotlin/KEEP).

## Navigate

* [Description of the current implementation](kotlin-coroutines-informal.md) (KEEP for Kotlin Coroutines)
* [Coroutines support library for Kotlin](https://github.com/kotlin/kotlinx.coroutines) (`kotlinx.coroutines`)
* [Kotlin coroutines design document](kotlin-coroutines-informal.md) (KEEP for Kotlin Coroutines)
* [Kotlin coroutines support library](https://github.com/kotlin/kotlinx.coroutines) (`kotlinx.coroutines`)

## Videos and presentations

Expand All @@ -27,7 +27,5 @@ It is logically a part of [KEEP](https://github.com/Kotlin/KEEP).

Please, submit feedback to:

* [Kotlin YouTrack](http://kotl.in/issue) on issues with implementation of coroutines in Kotlin compiler.
* [Kotlin YouTrack](http://kotl.in/issue) on issues with implementation of coroutines in Kotlin compiler and feature requests.
* [`kotlinx.coroutines`](https://github.com/Kotlin/kotlinx.coroutines/issues) on issues in supporting libraries.
* [`kotlin-coroutines`](https://github.com/JetBrains/kotlin-coroutines/issues) with suggestions on
language design improvements for coroutines.
5 changes: 2 additions & 3 deletions examples/channel/channel-example-1.kt
@@ -1,8 +1,7 @@
package channel.example1

import channel.go
import channel.mainBlocking
import delay.delay
import channel.*
import delay.*

// https://tour.golang.org/concurrency/1

Expand Down
5 changes: 1 addition & 4 deletions examples/channel/channel-example-2.kt
@@ -1,9 +1,6 @@
package channel.example2

import channel.Channel
import channel.SendChannel
import channel.go
import channel.mainBlocking
import channel.*

suspend fun sum(s: List<Int>, c: SendChannel<Int>) {
var sum = 0
Expand Down
7 changes: 2 additions & 5 deletions examples/channel/channel-example-2a.kt
@@ -1,10 +1,7 @@
package channel.example2a

import channel.Channel
import channel.SendChannel
import channel.go
import channel.mainBlocking
import kotlin.system.measureTimeMillis
import channel.*
import kotlin.system.*

suspend fun sum(s: List<Int>, c: SendChannel<Int>) {
// simulate long-running CPU-consuming computation
Expand Down
3 changes: 1 addition & 2 deletions examples/channel/channel-example-3.kt
@@ -1,7 +1,6 @@
package channel.example3

import channel.Channel
import channel.mainBlocking
import channel.*

// https://tour.golang.org/concurrency/3

Expand Down
5 changes: 1 addition & 4 deletions examples/channel/channel-example-4.kt
@@ -1,9 +1,6 @@
package channel.example4

import channel.Channel
import channel.SendChannel
import channel.go
import channel.mainBlocking
import channel.*

// https://tour.golang.org/concurrency/4

Expand Down
6 changes: 2 additions & 4 deletions examples/channel/channel-example-6.kt
@@ -1,9 +1,7 @@
package channel.example6

import channel.Time
import channel.mainBlocking
import channel.whileSelect
import delay.delay
import channel.*
import delay.*

// https://tour.golang.org/concurrency/6

Expand Down
5 changes: 1 addition & 4 deletions examples/channel/channel-example-8.kt
@@ -1,9 +1,6 @@
package channel.example8

import channel.Channel
import channel.SendChannel
import channel.go
import channel.mainBlocking
import channel.*
import java.util.*

// https://tour.golang.org/concurrency/7
Expand Down
7 changes: 3 additions & 4 deletions examples/channel/channel-example-9.kt
@@ -1,9 +1,8 @@
package channel.example9

import channel.go
import channel.mainBlocking
import delay.delay
import mutex.Mutex
import channel.*
import delay.*
import mutex.*

// https://tour.golang.org/concurrency/9

Expand Down
7 changes: 2 additions & 5 deletions examples/channel/channel-example-boring.kt
@@ -1,10 +1,7 @@
package channel.boring

import channel.Channel
import channel.ReceiveChannel
import channel.go
import channel.mainBlocking
import delay.delay
import channel.*
import delay.*
import java.util.*

// https://talks.golang.org/2012/concurrency.slide#25
Expand Down
7 changes: 2 additions & 5 deletions examples/channel/channel-example-multiplexing.kt
@@ -1,10 +1,7 @@
package channel.multiplexing

import channel.Channel
import channel.ReceiveChannel
import channel.boring.boring
import channel.go
import channel.mainBlocking
import channel.*
import channel.boring.*

// https://talks.golang.org/2012/concurrency.slide#27

Expand Down
2 changes: 1 addition & 1 deletion examples/channel/channel-example-multiplxing2.kt
@@ -1,7 +1,7 @@
package channel.multiplexing2

import channel.*
import channel.boring.boring
import channel.boring.*

// https://talks.golang.org/2012/concurrency.slide#27

Expand Down
10 changes: 5 additions & 5 deletions examples/channel/channel.kt
@@ -1,11 +1,9 @@
package channel

import java.util.*
import java.util.concurrent.atomic.AtomicLong
import java.util.concurrent.locks.ReentrantLock
import kotlin.coroutines.experimental.Continuation
import kotlin.coroutines.experimental.startCoroutine
import kotlin.coroutines.experimental.suspendCoroutine
import java.util.concurrent.atomic.*
import java.util.concurrent.locks.*
import kotlin.coroutines.*

interface SendChannel<T> {
suspend fun send(value: T)
Expand Down Expand Up @@ -147,6 +145,7 @@ class Channel<T>(val capacity: Int = 1) : SendChannel<T>, ReceiveChannel<T> {
if (wasClosed)
a.resumeClosed()
else
@Suppress("UNCHECKED_CAST")
a.resumeReceive(result as T)
return true
}
Expand Down Expand Up @@ -183,6 +182,7 @@ class Channel<T>(val capacity: Int = 1) : SendChannel<T>, ReceiveChannel<T> {
suspend override fun next(): T {
// return value previous acquired by hasNext
if (computedNext) {
@Suppress("UNCHECKED_CAST")
val result = nextValue as T
computedNext = false
nextValue = null
Expand Down
4 changes: 2 additions & 2 deletions examples/channel/go.kt
@@ -1,7 +1,7 @@
package channel

import context.CommonPool
import run.runBlocking
import context.*
import run.*

fun mainBlocking(block: suspend () -> Unit) = runBlocking(CommonPool, block)

Expand Down
10 changes: 5 additions & 5 deletions examples/channel/select.kt
@@ -1,9 +1,9 @@
package channel

import kotlin.coroutines.experimental.suspendCoroutine
import kotlin.coroutines.*

inline suspend fun <R> select(block: SelectorBuilder<R>.() -> Unit): R =
SelectorBuilder<R>().apply { block() }.doSelect()
suspend inline fun <R> select(block: SelectorBuilder<R>.() -> Unit): R =
SelectorBuilder<R>().apply { block() }.doSelect()

class SelectorBuilder<R> {
private val cases = mutableListOf<SelectCase<*, R>>()
Expand All @@ -23,7 +23,7 @@ class SelectorBuilder<R> {
suspend fun doSelect(): R {
require(!cases.isEmpty())
return suspendCoroutine { c ->
val selector = Selector<R>(c, cases)
val selector = Selector(c, cases)
for (case in cases) {
case.selector = selector
if (case.select(selector)) break
Expand All @@ -32,7 +32,7 @@ class SelectorBuilder<R> {
}
}

suspend fun whileSelect(block: SelectorBuilder<Boolean>.() -> Unit): Unit {
suspend fun whileSelect(block: SelectorBuilder<Boolean>.() -> Unit) {
while(select(block)) { /*loop*/ }
}

4 changes: 2 additions & 2 deletions examples/channel/time.kt
@@ -1,7 +1,7 @@
package channel

import delay.delay
import java.time.Instant
import delay.*
import java.time.*

object Time {
fun tick(millis: Long): ReceiveChannel<Instant> {
Expand Down
12 changes: 6 additions & 6 deletions examples/context/auth-example.kt
@@ -1,15 +1,15 @@
package context

import run.runBlocking
import kotlin.coroutines.experimental.suspendCoroutine
import run.*
import kotlin.coroutines.*

suspend fun secureAwait(): Unit = suspendCoroutine { cont ->
println("Current user is ${cont.context[AuthUser]?.name}")
cont.resume(Unit)
suspend fun doSomething() {
val currentUser = coroutineContext[AuthUser]?.name ?: throw SecurityException("unauthorized")
println("Current user is $currentUser")
}

fun main(args: Array<String>) {
runBlocking(AuthUser("admin")) {
secureAwait()
doSomething()
}
}
3 changes: 1 addition & 2 deletions examples/context/auth.kt
@@ -1,7 +1,6 @@
package context

import kotlin.coroutines.experimental.AbstractCoroutineContextElement
import kotlin.coroutines.experimental.CoroutineContext
import kotlin.coroutines.*

class AuthUser(val name: String) : AbstractCoroutineContextElement(AuthUser) {
companion object Key : CoroutineContext.Key<AuthUser>
Expand Down
7 changes: 3 additions & 4 deletions examples/context/pool-example.kt
@@ -1,9 +1,8 @@
package context

import future.await
import future.future
import run.runBlocking
import util.log
import future.*
import run.*
import util.*

fun main(args: Array<String>) = runBlocking(CommonPool) {
// multithreaded pool
Expand Down
38 changes: 15 additions & 23 deletions examples/context/pool.kt
@@ -1,20 +1,18 @@
package context

import run.launch
import java.util.concurrent.ForkJoinPool
import java.util.concurrent.ForkJoinWorkerThread
import kotlin.coroutines.experimental.AbstractCoroutineContextElement
import kotlin.coroutines.experimental.Continuation
import kotlin.coroutines.experimental.ContinuationInterceptor
import run.*
import java.util.concurrent.*
import kotlin.coroutines.*

object CommonPool : Pool(ForkJoinPool.commonPool())

open class Pool(val pool: ForkJoinPool) : AbstractCoroutineContextElement(ContinuationInterceptor), ContinuationInterceptor {
open class Pool(val pool: ForkJoinPool) : AbstractCoroutineContextElement(ContinuationInterceptor),
ContinuationInterceptor {
override fun <T> interceptContinuation(continuation: Continuation<T>): Continuation<T> =
PoolContinuation(pool, continuation.context.fold(continuation, { cont, element ->
if (element != this@Pool && element is ContinuationInterceptor)
element.interceptContinuation(cont) else cont
}))
PoolContinuation(pool, continuation.context.fold(continuation) { cont, element ->
if (element != this@Pool && element is ContinuationInterceptor)
element.interceptContinuation(cont) else cont
})

// runs new coroutine in this pool in parallel (schedule to a different thread)
fun runParallel(block: suspend () -> Unit) {
Expand All @@ -23,18 +21,12 @@ open class Pool(val pool: ForkJoinPool) : AbstractCoroutineContextElement(Contin
}

private class PoolContinuation<T>(
val pool: ForkJoinPool,
val continuation: Continuation<T>
) : Continuation<T> by continuation {
override fun resume(value: T) {
if (isPoolThread()) continuation.resume(value)
else pool.execute { continuation.resume(value) }
}
val pool: ForkJoinPool,
val cont: Continuation<T>
) : Continuation<T> {
override val context: CoroutineContext = cont.context

override fun resumeWithException(exception: Throwable) {
if (isPoolThread()) continuation.resumeWithException(exception)
else pool.execute { continuation.resumeWithException(exception) }
override fun resumeWith(result: Result<T>) {
pool.execute { cont.resumeWith(result) }
}

fun isPoolThread(): Boolean = (Thread.currentThread() as? ForkJoinWorkerThread)?.pool == pool
}
4 changes: 2 additions & 2 deletions examples/context/swing-delay-example.kt
@@ -1,7 +1,7 @@
package context

import future.future
import util.log
import future.*
import util.*

fun main(args: Array<String>) {
future(Swing) {
Expand Down
4 changes: 2 additions & 2 deletions examples/context/swing-delay.kt
@@ -1,7 +1,7 @@
package context

import javax.swing.Timer
import kotlin.coroutines.experimental.suspendCoroutine
import javax.swing.*
import kotlin.coroutines.*

suspend fun Swing.delay(millis: Int): Unit = suspendCoroutine { cont ->
Timer(millis) { cont.resume(Unit) }.apply {
Expand Down
8 changes: 4 additions & 4 deletions examples/context/swing-example.kt
@@ -1,9 +1,9 @@
package context

import run.launch
import util.log
import java.util.concurrent.ForkJoinPool
import kotlin.coroutines.experimental.suspendCoroutine
import run.*
import util.*
import java.util.concurrent.*
import kotlin.coroutines.*

suspend fun makeRequest(): String {
log("Making request...")
Expand Down

1 comment on commit 0904690

@johndpope
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry to bomb this commit with a support issue - but there's no way to log a support issue here - I don't have problem with coroutines - just getting the kotlin code running. I noticed many people use intellij - I'm using vscode which has built in kotlin run time debugging.
I simply need the correct way to execute code without having specific ide.
seems this code helps things run.
https://github.com/Kotlin/coroutines-examples/blob/master/.idea/libraries/KotlinJavaRuntime.xml
here's what happens in vscode
https://gist.github.com/johndpope/475793fbd5c91065e67896d148dcbd9e

Please sign in to comment.