Created
July 26, 2019 19:45
-
-
Save Groostav/c0d6d7625db61045064b45b51a51b6d9 to your computer and use it in GitHub Desktop.
first crack at mutable event bus context
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class EventContext(key: Key): AbstractCoroutineContextElement(key) { | |
private val completed = CompletableDeferred<Unit>() | |
private var events: AtomicReference<ImmutableList<EventWrapper>?> = AtomicReference(immutableListOf()) | |
// in this implementation, polling an empty list "closes" it, | |
// thus, if you poll a list of 1 element, it becomes a list of 0 elements, | |
// when thats polled, its atomically closed and subsequent offer calls return false. | |
fun poll(): EventWrapper? { | |
var initial: ImmutableList<EventWrapper>? | |
var final: ImmutableList<EventWrapper>? | |
var result: EventWrapper? | |
do { | |
initial = events.get() | |
result = initial?.firstOrNull() | |
final = when { | |
initial == null -> null | |
initial.isEmpty() -> null | |
else -> initial.removeAt(0) | |
} | |
} | |
while( ! events.compareAndSet(initial, final)) | |
if(initial != null && final == null){ | |
// polled an empty queue completing it | |
completed.complete(Unit) | |
} | |
return result | |
} | |
fun offer(event: EventWrapper): Boolean { | |
val result = events.updateAndGet { if(it == null) it else (it + event) } | |
println("offered event ${event.event}: $result") | |
return result != null && (event == result.lastOrNull() || event in result) | |
} | |
//suspends until this nested event loops is completed | |
suspend fun await() = completed.await() | |
// unsafe-poll the state of completion (meant for debugging) | |
val isCompleted: Boolean get() = completed.isCompleted | |
//need difference in equality for different event busses | |
// => do not use object | |
class Key: CoroutineContext.Key<EventContext> | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment