Skip to content

Commit

Permalink
Added explicitApi
Browse files Browse the repository at this point in the history
  • Loading branch information
jeggy committed Jun 13, 2021
1 parent b5af974 commit 460cc83
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 47 deletions.
7 changes: 6 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import de.marcphilipp.gradle.nexus.NexusPublishPlugin
import org.jetbrains.dokka.Platform
import java.time.Duration

plugins {
Expand All @@ -25,6 +26,10 @@ val sonatypePassword: String? = System.getenv("sonatypePassword")
group = "com.apurebase"
version = libVersion

kotlin {
explicitApi()
}

dependencies {
implementation(kotlin("stdlib-common"))
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesVersion")
Expand Down Expand Up @@ -55,7 +60,7 @@ tasks {
configureEach {
jdkVersion.set(8)
reportUndocumented.set(true)
platform.set(org.jetbrains.dokka.Platform.jvm)
platform.set(Platform.jvm)
}
}
}
Expand Down
21 changes: 11 additions & 10 deletions src/main/kotlin/com/apurebase/deferredJson/DeferredJsonArray.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,50 +9,51 @@ import kotlinx.serialization.json.JsonElement
import kotlin.coroutines.CoroutineContext


class DeferredJsonArray internal constructor(
@Suppress("SuspendFunctionOnCoroutineScope")
public class DeferredJsonArray internal constructor(
ctx: CoroutineContext
): CoroutineScope, Mutex by Mutex() {

private val job = SupervisorJob()
override val coroutineContext = (ctx + job)
private val job = Job()
override val coroutineContext: CoroutineContext = ctx + job

private val deferredArray = mutableListOf<Deferred<JsonElement>>()
private var completedArray: List<JsonElement>? = null

suspend fun addValue(element: JsonElement) {
public suspend fun addValue(element: JsonElement) {
addDeferredValue(CompletableDeferred(element))
}

suspend fun addDeferredValue(element: Deferred<JsonElement>) = withLock {
public suspend fun addDeferredValue(element: Deferred<JsonElement>): Unit = withLock {
deferredArray.add(element)
}

suspend fun addDeferredObj(block: suspend DeferredJsonMap.() -> Unit) {
public suspend fun addDeferredObj(block: suspend DeferredJsonMap.() -> Unit) {
val map = DeferredJsonMap(job)
block(map)
addDeferredValue(async(job, LAZY) { map.awaitAndBuild() })
}

suspend fun addDeferredArray(block: suspend DeferredJsonArray.() -> Unit) {
public suspend fun addDeferredArray(block: suspend DeferredJsonArray.() -> Unit) {
val array = DeferredJsonArray(job)
block(array)
addDeferredValue(array.asDeferred())
}

fun asDeferred() : Deferred<JsonElement> {
internal fun asDeferred() : Deferred<JsonElement> {
return async(job, LAZY) {
awaitAll()
build()
}
}

suspend fun awaitAll() {
public suspend fun awaitAll() {
check(completedArray == null) { "The deferred tree has already been awaited!" }
completedArray = deferredArray.awaitAll()
job.complete()
}

fun build(): JsonArray {
public fun build(): JsonArray {
checkNotNull(completedArray) { "The deferred tree has not been awaited!" }
return JsonArray(completedArray!!)
}
Expand Down
46 changes: 13 additions & 33 deletions src/main/kotlin/com/apurebase/deferredJson/DeferredJsonMap.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,14 @@ import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.JsonPrimitive
import kotlin.coroutines.CoroutineContext

val all = mutableListOf<DeferredJsonMap>()

class DeferredJsonMap internal constructor(
val ctx: CoroutineContext,
val isRoot: Boolean = false
public class DeferredJsonMap internal constructor(
ctx: CoroutineContext,
): CoroutineScope {

internal val job = Job()
override val coroutineContext = ctx + job + CoroutineName("isRoot: $isRoot")
override val coroutineContext: CoroutineContext = ctx + job

private val dmLock = Mutex()
private val deferredMap = mutableMapOf<String, Deferred<JsonElement>>()
Expand All @@ -28,19 +24,15 @@ class DeferredJsonMap internal constructor(

private var completedMap: Map<String, JsonElement>? = null

init {
all.add(this)
}

suspend infix fun String.toValue(element: JsonElement) {
public suspend infix fun String.toValue(element: JsonElement) {
this toDeferredValue CompletableDeferred(element)
}

infix fun String.toDeferredValue(element: Deferred<JsonElement>) {
public suspend infix fun String.toDeferredValue(element: Deferred<JsonElement>): Unit = dmLock.withLock {
deferredMap[this] = element
}

suspend infix fun String.toDeferredObj(block: suspend DeferredJsonMap.() -> Unit) {
public suspend infix fun String.toDeferredObj(block: suspend DeferredJsonMap.() -> Unit) {
val mapToUse = uddmLock.withLock {
val map = unDefinedDeferredMap[this]
if (map == null) {
Expand All @@ -52,48 +44,36 @@ class DeferredJsonMap internal constructor(
block(mapToUse)
}

suspend infix fun String.toDeferredArray(block: suspend DeferredJsonArray.() -> Unit) {
public suspend infix fun String.toDeferredArray(block: suspend DeferredJsonArray.() -> Unit) {
val array = DeferredJsonArray(job)
block(array)
this@toDeferredArray toDeferredValue array.asDeferred()
}

private fun asDeferredAsync(startIn: Job = job) : Deferred<JsonElement> = async(startIn + CoroutineName("$ctx - create as deferred"), LAZY) {
private fun asDeferredAsync(startIn: Job = job): Deferred<JsonElement> = async(startIn, LAZY) {
awaitAll()
build()
}

private suspend fun awaitAll() {
if (completedMap != null) {
println("The deferred tree has already been awaited!")
return
}

println("$job | map:awaitAll #1")

if (completedMap != null) return

do {
println("$job | map:awaitAll #do")
moreJobs.awaitAll()
unDefinedDeferredMap.map { (key, map) ->
key toDeferredValue map.asDeferredAsync(job)
}
} while (moreJobs.any { !it.isCompleted })

println("$job | map:awaitAll #2")
job.children.toList().joinAll()
println("$job | map:awaitAll #3")
job.complete()


println("$job | map:awaitAll #4")
job.join()
completedMap = deferredMap.mapValues { it.value.await() }
}

suspend fun deferredLaunch(block: suspend DeferredJsonMap.() -> Unit) = mjLock.withLock {
println("$job | ")
moreJobs.add(async(job + CoroutineName("$ctx deferredLaunch"), LAZY) {
@Suppress("SuspendFunctionOnCoroutineScope")
public suspend fun deferredLaunch(block: suspend DeferredJsonMap.() -> Unit): Unit = mjLock.withLock {
moreJobs.add(async(job, LAZY) {
block(this@DeferredJsonMap)
})
}
Expand All @@ -104,5 +84,5 @@ class DeferredJsonMap internal constructor(
return JsonObject(completedMap!!)
}

suspend fun awaitAndBuild():JsonObject { awaitAll(); return build() }
public suspend fun awaitAndBuild():JsonObject { awaitAll(); return build() }
}
5 changes: 2 additions & 3 deletions src/main/kotlin/com/apurebase/deferredJson/builder.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@ package com.apurebase.deferredJson
import kotlinx.coroutines.*
import kotlinx.serialization.json.JsonObject

fun CoroutineScope.deferredJsonBuilder(
public fun CoroutineScope.deferredJsonBuilder(
timeout: Long? = null,
init: suspend DeferredJsonMap.() -> Unit
): Deferred<JsonObject> = async {
val block: suspend CoroutineScope.() -> JsonObject = {
try {
val builder = DeferredJsonMap(coroutineContext, true)
println("Root: ${builder.job}")
val builder = DeferredJsonMap(coroutineContext)
builder.init()
builder.awaitAndBuild()
} catch (e: CancellationException) {
Expand Down

0 comments on commit 460cc83

Please sign in to comment.