Skip to content

Instantly share code, notes, and snippets.

@Groostav
Created February 10, 2019 01:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Groostav/c61c4df0eb5b272110fe1bd44d2cc705 to your computer and use it in GitHub Desktop.
Save Groostav/c61c4df0eb5b272110fe1bd44d2cc705 to your computer and use it in GitHub Desktop.
class Test {
@Volatile
var ticker = 0
@Volatile
var deferred: Deferred<String>
val retryingExceptionHandler: CoroutineExceptionHandler = CoroutineExceptionHandler { _, throwable ->
println("!!!!!!!")
authScope.kickoffUpdateWithDelay()
authScope.testB()
}
val authScope = CoroutineScope(SupervisorJob() + Dispatchers.IO + retryingExceptionHandler)
init {
deferred = authScope.async { getSome() }
authScope.testB()
}
fun CoroutineScope.kickoffUpdateWithDelay() = launch {
delay(100)
deferred = authScope.async { getSome() }
}
suspend fun getSome(): String {
if (ticker < 5) {
delay(1)
ticker += 1
throw Exception()
} else {
delay(1)
ticker += 1
return "PASSSED"
}
}
fun CoroutineScope.testB() = launch {
deferred.await()
if (ticker < 5) {
ticker += 1
throw Exception()
} else {
ticker += 1
println("PASSSED")
}
}
}
fun main(args: Array<String>) = runBlocking<Unit> {
Test()
repeat(100) {
delay(100)
}
}
@ExperimentalCoroutinesApi
class _Test {
val mutex = Mutex()
data class State(val ticker: Int, val producerJob: Job?){
fun increment() = copy(ticker = ticker + 1)
}
val results = ConflatedBroadcastChannel<String>()
@Volatile
var state = State(0, null)
val retryingExceptionHandler: CoroutineExceptionHandler = CoroutineExceptionHandler { _, throwable ->
println("!!!!!!!")
authScope.kickoffUpdateWithDelay()
authScope.testB()
}
val authScope = CoroutineScope(SupervisorJob() + Dispatchers.IO + retryingExceptionHandler)
init {
require(mutex.tryLock())
try {
state = state.copy(producerJob = authScope.launch { getSome() })
}
finally {
mutex.unlock()
}
}
fun CoroutineScope.kickoffUpdateWithDelay() = launch {
delay(100)
mutex.withLock {
if(state.producerJob?.isCancelled == true){
state = state.copy(producerJob = authScope.launch { getSome() })
}
}
}
suspend fun getSome(): Unit {
if (state.ticker < 5) {
delay(1)
mutex.withLock { state = state.increment() }
throw Exception()
} else {
delay(1)
mutex.withLock { state = state.increment() }
results.send("PASSSED")
}
}
fun CoroutineScope.testB() = launch {
state.producerJob?.join()
//important difference between join() and await():
// await() will throw the exception thrown by the block of the deferred,
// where join() will not.
if (state.ticker < 5) {
mutex.withLock { state = state.increment() }
throw Exception()
} else {
mutex.withLock { state = state.increment() }
results.send("testB: PASSSED")
}
}
}
fun main(args: Array<String>) = runBlocking<Unit> {
_Test()
repeat(100) {
delay(100)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment