diff options
14 files changed, 347 insertions, 366 deletions
diff --git a/gradle.properties b/gradle.properties index 4b91410d..c0e03214 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,9 +1,9 @@ group=pl.treksoft version=0.0.20 -kotlinVersion=1.3.0 +kotlinVersion=1.3.11 javaVersion=1.8 -coroutinesVersion=1.0.0 -serializationVersion=0.9.0 +coroutinesVersion=1.0.1 +serializationVersion=0.9.1 frontendPluginVersion=0.0.37 dokkaVersion=0.9.17 detektVersion=1.0.0.RC9.2 diff --git a/kvision-modules/kvision-common/src/main/kotlin/pl/treksoft/kvision/remote/JoobyServiceManager.kt b/kvision-modules/kvision-common/src/main/kotlin/pl/treksoft/kvision/remote/JoobyServiceManager.kt index dceae898..cb1b44d0 100644 --- a/kvision-modules/kvision-common/src/main/kotlin/pl/treksoft/kvision/remote/JoobyServiceManager.kt +++ b/kvision-modules/kvision-common/src/main/kotlin/pl/treksoft/kvision/remote/JoobyServiceManager.kt @@ -21,8 +21,6 @@ */ package pl.treksoft.kvision.remote -import kotlinx.coroutines.Deferred - /** * Multiplatform service manager for Jooby. */ @@ -35,7 +33,7 @@ expect open class JoobyServiceManager<T : Any>(service: T) : ServiceManager { * @param method a HTTP method */ protected inline fun <reified RET> bind( - noinline function: T.(Request?) -> Deferred<RET>, + noinline function: suspend T.(Request?) -> RET, route: String? = null, method: RpcHttpMethod = RpcHttpMethod.POST ) @@ -47,7 +45,7 @@ expect open class JoobyServiceManager<T : Any>(service: T) : ServiceManager { * @param method a HTTP method */ protected inline fun <reified PAR, reified RET> bind( - noinline function: T.(PAR, Request?) -> Deferred<RET>, + noinline function: suspend T.(PAR, Request?) -> RET, route: String? = null, method: RpcHttpMethod = RpcHttpMethod.POST ) @@ -59,7 +57,7 @@ expect open class JoobyServiceManager<T : Any>(service: T) : ServiceManager { * @param method a HTTP method */ protected inline fun <reified PAR1, reified PAR2, reified RET> bind( - noinline function: T.(PAR1, PAR2, Request?) -> Deferred<RET>, + noinline function: suspend T.(PAR1, PAR2, Request?) -> RET, route: String? = null, method: RpcHttpMethod = RpcHttpMethod.POST ) @@ -71,7 +69,7 @@ expect open class JoobyServiceManager<T : Any>(service: T) : ServiceManager { * @param method a HTTP method */ protected inline fun <reified PAR1, reified PAR2, reified PAR3, reified RET> bind( - noinline function: T.(PAR1, PAR2, PAR3, Request?) -> Deferred<RET>, + noinline function: suspend T.(PAR1, PAR2, PAR3, Request?) -> RET, route: String? = null, method: RpcHttpMethod = RpcHttpMethod.POST ) @@ -83,7 +81,7 @@ expect open class JoobyServiceManager<T : Any>(service: T) : ServiceManager { * @param method a HTTP method */ protected inline fun <reified PAR1, reified PAR2, reified PAR3, reified PAR4, reified RET> bind( - noinline function: T.(PAR1, PAR2, PAR3, PAR4, Request?) -> Deferred<RET>, + noinline function: suspend T.(PAR1, PAR2, PAR3, PAR4, Request?) -> RET, route: String? = null, method: RpcHttpMethod = RpcHttpMethod.POST ) @@ -95,7 +93,7 @@ expect open class JoobyServiceManager<T : Any>(service: T) : ServiceManager { * @param method a HTTP method */ protected inline fun <reified PAR1, reified PAR2, reified PAR3, reified PAR4, reified PAR5, reified RET> bind( - noinline function: T.(PAR1, PAR2, PAR3, PAR4, PAR5, Request?) -> Deferred<RET>, + noinline function: suspend T.(PAR1, PAR2, PAR3, PAR4, PAR5, Request?) -> RET, route: String? = null, method: RpcHttpMethod = RpcHttpMethod.POST ) diff --git a/kvision-modules/kvision-common/src/main/kotlin/pl/treksoft/kvision/remote/SpringServiceManager.kt b/kvision-modules/kvision-common/src/main/kotlin/pl/treksoft/kvision/remote/SpringServiceManager.kt index 0e17d4e7..90926656 100644 --- a/kvision-modules/kvision-common/src/main/kotlin/pl/treksoft/kvision/remote/SpringServiceManager.kt +++ b/kvision-modules/kvision-common/src/main/kotlin/pl/treksoft/kvision/remote/SpringServiceManager.kt @@ -21,7 +21,6 @@ */ package pl.treksoft.kvision.remote -import kotlinx.coroutines.Deferred import kotlin.reflect.KClass /** @@ -36,7 +35,7 @@ expect open class SpringServiceManager<T : Any>(serviceClass: KClass<T>) : Servi * @param method a HTTP method */ protected inline fun <reified RET> bind( - noinline function: T.() -> Deferred<RET>, + noinline function: suspend T.() -> RET, route: String? = null, method: RpcHttpMethod = RpcHttpMethod.POST ) @@ -48,7 +47,7 @@ expect open class SpringServiceManager<T : Any>(serviceClass: KClass<T>) : Servi * @param method a HTTP method */ protected inline fun <reified PAR, reified RET> bind( - noinline function: T.(PAR) -> Deferred<RET>, + noinline function: suspend T.(PAR) -> RET, route: String? = null, method: RpcHttpMethod = RpcHttpMethod.POST ) @@ -60,7 +59,7 @@ expect open class SpringServiceManager<T : Any>(serviceClass: KClass<T>) : Servi * @param method a HTTP method */ protected inline fun <reified PAR1, reified PAR2, reified RET> bind( - noinline function: T.(PAR1, PAR2) -> Deferred<RET>, + noinline function: suspend T.(PAR1, PAR2) -> RET, route: String? = null, method: RpcHttpMethod = RpcHttpMethod.POST ) @@ -72,7 +71,7 @@ expect open class SpringServiceManager<T : Any>(serviceClass: KClass<T>) : Servi * @param method a HTTP method */ protected inline fun <reified PAR1, reified PAR2, reified PAR3, reified RET> bind( - noinline function: T.(PAR1, PAR2, PAR3) -> Deferred<RET>, + noinline function: suspend T.(PAR1, PAR2, PAR3) -> RET, route: String? = null, method: RpcHttpMethod = RpcHttpMethod.POST ) @@ -84,7 +83,7 @@ expect open class SpringServiceManager<T : Any>(serviceClass: KClass<T>) : Servi * @param method a HTTP method */ protected inline fun <reified PAR1, reified PAR2, reified PAR3, reified PAR4, reified RET> bind( - noinline function: T.(PAR1, PAR2, PAR3, PAR4) -> Deferred<RET>, + noinline function: suspend T.(PAR1, PAR2, PAR3, PAR4) -> RET, route: String? = null, method: RpcHttpMethod = RpcHttpMethod.POST ) @@ -96,7 +95,7 @@ expect open class SpringServiceManager<T : Any>(serviceClass: KClass<T>) : Servi * @param method a HTTP method */ protected inline fun <reified PAR1, reified PAR2, reified PAR3, reified PAR4, reified PAR5, reified RET> bind( - noinline function: T.(PAR1, PAR2, PAR3, PAR4, PAR5) -> Deferred<RET>, + noinline function: suspend T.(PAR1, PAR2, PAR3, PAR4, PAR5) -> RET, route: String? = null, method: RpcHttpMethod = RpcHttpMethod.POST ) diff --git a/kvision-modules/kvision-server-jooby/src/main/kotlin/pl/treksoft/kvision/remote/JoobyServiceManager.kt b/kvision-modules/kvision-server-jooby/src/main/kotlin/pl/treksoft/kvision/remote/JoobyServiceManager.kt index 1d5cd926..17f51443 100644 --- a/kvision-modules/kvision-server-jooby/src/main/kotlin/pl/treksoft/kvision/remote/JoobyServiceManager.kt +++ b/kvision-modules/kvision-server-jooby/src/main/kotlin/pl/treksoft/kvision/remote/JoobyServiceManager.kt @@ -22,8 +22,10 @@ package pl.treksoft.kvision.remote import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper -import kotlinx.coroutines.Deferred -import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.CoroutineStart +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch import org.jooby.Response import org.slf4j.Logger import org.slf4j.LoggerFactory @@ -32,6 +34,7 @@ import java.text.SimpleDateFormat /** * Multiplatform service manager for Jooby. */ +@UseExperimental(ExperimentalCoroutinesApi::class) actual open class JoobyServiceManager<T : Any> actual constructor(val service: T) : ServiceManager { companion object { @@ -52,24 +55,26 @@ actual open class JoobyServiceManager<T : Any> actual constructor(val service: T */ @Suppress("TooGenericExceptionCaught") protected actual inline fun <reified RET> bind( - noinline function: T.(Request?) -> Deferred<RET>, + noinline function: suspend T.(Request?) -> RET, route: String?, method: RpcHttpMethod ) { val routeDef = route ?: "route${this::class.simpleName}${counter++}" routes.add { call(method, "/kv/$routeDef") { req, res -> val jsonRpcRequest = req.body(JsonRpcRequest::class.java) - try { - val result = runBlocking { function.invoke(service, req).await() } - res.send( - JsonRpcResponse( - id = jsonRpcRequest.id, - result = mapper.writeValueAsString(result) + GlobalScope.launch(start = CoroutineStart.UNDISPATCHED) { + try { + val result = function.invoke(service, req) + res.send( + JsonRpcResponse( + id = jsonRpcRequest.id, + result = mapper.writeValueAsString(result) + ) ) - ) - } catch (e: Exception) { - LOG.error(e.message, e) - res.send(JsonRpcResponse(id = jsonRpcRequest.id, error = e.message ?: "Error")) + } catch (e: Exception) { + LOG.error(e.message, e) + res.send(JsonRpcResponse(id = jsonRpcRequest.id, error = e.message ?: "Error")) + } } }.invoke(this) } @@ -83,7 +88,7 @@ actual open class JoobyServiceManager<T : Any> actual constructor(val service: T */ @Suppress("TooGenericExceptionCaught") protected actual inline fun <reified PAR, reified RET> bind( - noinline function: T.(PAR, Request?) -> Deferred<RET>, + noinline function: suspend T.(PAR, Request?) -> RET, route: String?, method: RpcHttpMethod ) { val routeDef = route ?: "route${this::class.simpleName}${counter++}" @@ -92,17 +97,19 @@ actual open class JoobyServiceManager<T : Any> actual constructor(val service: T val jsonRpcRequest = req.body(JsonRpcRequest::class.java) if (jsonRpcRequest.params.size == 1) { val param = getParameter<PAR>(jsonRpcRequest.params[0]) - try { - val result = runBlocking { function.invoke(service, param, req).await() } - res.send( - JsonRpcResponse( - id = jsonRpcRequest.id, - result = mapper.writeValueAsString(result) + GlobalScope.launch(start = CoroutineStart.UNDISPATCHED) { + try { + val result = function.invoke(service, param, req) + res.send( + JsonRpcResponse( + id = jsonRpcRequest.id, + result = mapper.writeValueAsString(result) + ) ) - ) - } catch (e: Exception) { - LOG.error(e.message, e) - res.send(JsonRpcResponse(id = jsonRpcRequest.id, error = e.message ?: "Error")) + } catch (e: Exception) { + LOG.error(e.message, e) + res.send(JsonRpcResponse(id = jsonRpcRequest.id, error = e.message ?: "Error")) + } } } else { res.send(JsonRpcResponse(id = jsonRpcRequest.id, error = "Invalid parameters")) @@ -119,7 +126,7 @@ actual open class JoobyServiceManager<T : Any> actual constructor(val service: T */ @Suppress("TooGenericExceptionCaught") protected actual inline fun <reified PAR1, reified PAR2, reified RET> bind( - noinline function: T.(PAR1, PAR2, Request?) -> Deferred<RET>, + noinline function: suspend T.(PAR1, PAR2, Request?) -> RET, route: String?, method: RpcHttpMethod ) { val routeDef = route ?: "route${this::class.simpleName}${counter++}" @@ -129,17 +136,19 @@ actual open class JoobyServiceManager<T : Any> actual constructor(val service: T if (jsonRpcRequest.params.size == 2) { val param1 = getParameter<PAR1>(jsonRpcRequest.params[0]) val param2 = getParameter<PAR2>(jsonRpcRequest.params[1]) - try { - val result = runBlocking { function.invoke(service, param1, param2, req).await() } - res.send( - JsonRpcResponse( - id = jsonRpcRequest.id, - result = mapper.writeValueAsString(result) + GlobalScope.launch(start = CoroutineStart.UNDISPATCHED) { + try { + val result = function.invoke(service, param1, param2, req) + res.send( + JsonRpcResponse( + id = jsonRpcRequest.id, + result = mapper.writeValueAsString(result) + ) ) - ) - } catch (e: Exception) { - LOG.error(e.message, e) - res.send(JsonRpcResponse(id = jsonRpcRequest.id, error = e.message ?: "Error")) + } catch (e: Exception) { + LOG.error(e.message, e) + res.send(JsonRpcResponse(id = jsonRpcRequest.id, error = e.message ?: "Error")) + } } } else { res.send(JsonRpcResponse(id = jsonRpcRequest.id, error = "Invalid parameters")) @@ -156,7 +165,7 @@ actual open class JoobyServiceManager<T : Any> actual constructor(val service: T */ @Suppress("TooGenericExceptionCaught") protected actual inline fun <reified PAR1, reified PAR2, reified PAR3, reified RET> bind( - noinline function: T.(PAR1, PAR2, PAR3, Request?) -> Deferred<RET>, + noinline function: suspend T.(PAR1, PAR2, PAR3, Request?) -> RET, route: String?, method: RpcHttpMethod ) { val routeDef = route ?: "route${this::class.simpleName}${counter++}" @@ -168,17 +177,19 @@ actual open class JoobyServiceManager<T : Any> actual constructor(val service: T val param1 = getParameter<PAR1>(jsonRpcRequest.params[0]) val param2 = getParameter<PAR2>(jsonRpcRequest.params[1]) val param3 = getParameter<PAR3>(jsonRpcRequest.params[2]) - try { - val result = runBlocking { function.invoke(service, param1, param2, param3, req).await() } - res.send( - JsonRpcResponse( - id = jsonRpcRequest.id, - result = mapper.writeValueAsString(result) + GlobalScope.launch(start = CoroutineStart.UNDISPATCHED) { + try { + val result = function.invoke(service, param1, param2, param3, req) + res.send( + JsonRpcResponse( + id = jsonRpcRequest.id, + result = mapper.writeValueAsString(result) + ) ) - ) - } catch (e: Exception) { - LOG.error(e.message, e) - res.send(JsonRpcResponse(id = jsonRpcRequest.id, error = e.message ?: "Error")) + } catch (e: Exception) { + LOG.error(e.message, e) + res.send(JsonRpcResponse(id = jsonRpcRequest.id, error = e.message ?: "Error")) + } } } else { res.send(JsonRpcResponse(id = jsonRpcRequest.id, error = "Invalid parameters")) @@ -195,7 +206,7 @@ actual open class JoobyServiceManager<T : Any> actual constructor(val service: T */ @Suppress("TooGenericExceptionCaught") protected actual inline fun <reified PAR1, reified PAR2, reified PAR3, reified PAR4, reified RET> bind( - noinline function: T.(PAR1, PAR2, PAR3, PAR4, Request?) -> Deferred<RET>, + noinline function: suspend T.(PAR1, PAR2, PAR3, PAR4, Request?) -> RET, route: String?, method: RpcHttpMethod ) { val routeDef = route ?: "route${this::class.simpleName}${counter++}" @@ -208,18 +219,19 @@ actual open class JoobyServiceManager<T : Any> actual constructor(val service: T val param2 = getParameter<PAR2>(jsonRpcRequest.params[1]) val param3 = getParameter<PAR3>(jsonRpcRequest.params[2]) val param4 = getParameter<PAR4>(jsonRpcRequest.params[3]) - try { - val result = - runBlocking { function.invoke(service, param1, param2, param3, param4, req).await() } - res.send( - JsonRpcResponse( - id = jsonRpcRequest.id, - result = mapper.writeValueAsString(result) + GlobalScope.launch(start = CoroutineStart.UNDISPATCHED) { + try { + val result = function.invoke(service, param1, param2, param3, param4, req) + res.send( + JsonRpcResponse( + id = jsonRpcRequest.id, + result = mapper.writeValueAsString(result) + ) ) - ) - } catch (e: Exception) { - LOG.error(e.message, e) - res.send(JsonRpcResponse(id = jsonRpcRequest.id, error = e.message ?: "Error")) + } catch (e: Exception) { + LOG.error(e.message, e) + res.send(JsonRpcResponse(id = jsonRpcRequest.id, error = e.message ?: "Error")) + } } } else { res.send(JsonRpcResponse(id = jsonRpcRequest.id, error = "Invalid parameters")) @@ -237,7 +249,7 @@ actual open class JoobyServiceManager<T : Any> actual constructor(val service: T @Suppress("TooGenericExceptionCaught") protected actual inline fun <reified PAR1, reified PAR2, reified PAR3, reified PAR4, reified PAR5, reified RET> bind( - noinline function: T.(PAR1, PAR2, PAR3, PAR4, PAR5, Request?) -> Deferred<RET>, + noinline function: suspend T.(PAR1, PAR2, PAR3, PAR4, PAR5, Request?) -> RET, route: String?, method: RpcHttpMethod ) { @@ -252,20 +264,19 @@ actual open class JoobyServiceManager<T : Any> actual constructor(val service: T val param3 = getParameter<PAR3>(jsonRpcRequest.params[2]) val param4 = getParameter<PAR4>(jsonRpcRequest.params[3]) val param5 = getParameter<PAR5>(jsonRpcRequest.params[4]) - try { - val result = - runBlocking { - function.invoke(service, param1, param2, param3, param4, param5, req).await() - } - res.send( - JsonRpcResponse( - id = jsonRpcRequest.id, - result = mapper.writeValueAsString(result) + GlobalScope.launch(start = CoroutineStart.UNDISPATCHED) { + try { + val result = function.invoke(service, param1, param2, param3, param4, param5, req) + res.send( + JsonRpcResponse( + id = jsonRpcRequest.id, + result = mapper.writeValueAsString(result) + ) ) - ) - } catch (e: Exception) { - LOG.error(e.message, e) - res.send(JsonRpcResponse(id = jsonRpcRequest.id, error = e.message ?: "Error")) + } catch (e: Exception) { + LOG.error(e.message, e) + res.send(JsonRpcResponse(id = jsonRpcRequest.id, error = e.message ?: "Error")) + } } } else { res.send(JsonRpcResponse(id = jsonRpcRequest.id, error = "Invalid parameters")) diff --git a/kvision-modules/kvision-server-jooby/src/main/kotlin/pl/treksoft/kvision/remote/KVServer.kt b/kvision-modules/kvision-server-jooby/src/main/kotlin/pl/treksoft/kvision/remote/KVServer.kt index bc182467..c2321911 100644 --- a/kvision-modules/kvision-server-jooby/src/main/kotlin/pl/treksoft/kvision/remote/KVServer.kt +++ b/kvision-modules/kvision-server-jooby/src/main/kotlin/pl/treksoft/kvision/remote/KVServer.kt @@ -22,10 +22,6 @@ package pl.treksoft.kvision.remote import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper -import kotlinx.coroutines.CoroutineStart -import kotlinx.coroutines.Deferred -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.GlobalScope import org.jooby.Kooby import org.jooby.Session import org.jooby.json.Jackson @@ -63,36 +59,20 @@ actual typealias Request = org.jooby.Request actual typealias Profile = CommonProfile /** - * A helper extension function for asynchronous request processing. - */ -@UseExperimental(ExperimentalCoroutinesApi::class) -fun <RESP> Request?.async(block: (Request) -> RESP): Deferred<RESP> = this?.let { req -> - GlobalScope.coroutinesAsync(start = CoroutineStart.UNDISPATCHED) { - block(req) - } -} ?: throw IllegalStateException("Request not set!") - -/** * A helper extension function for asynchronous request processing with session. */ -@UseExperimental(ExperimentalCoroutinesApi::class) -fun <RESP> Request?.asyncSession(block: (Request, Session) -> RESP): Deferred<RESP> = this?.let { req -> +fun <RESP> Request?.withSession(block: (Request, Session) -> RESP): RESP = this?.let { req -> val session = req.session() - GlobalScope.coroutinesAsync(start = CoroutineStart.UNDISPATCHED) { - block(req, session) - } + block(req, session) } ?: throw IllegalStateException("Request not set!") /** * A helper extension function for asynchronous request processing with session and user profile. */ -@UseExperimental(ExperimentalCoroutinesApi::class) -fun <RESP> Request?.asyncAuth(block: (Request, Session, Profile) -> RESP): Deferred<RESP> = this?.let { req -> +fun <RESP> Request?.withProfile(block: (Request, Session, Profile) -> RESP): RESP = this?.let { req -> val session = req.session() val profile = req.require(CommonProfile::class.java) as CommonProfile? profile?.let { - GlobalScope.coroutinesAsync(start = CoroutineStart.UNDISPATCHED) { - block(req, session, profile) - } + block(req, session, profile) } } ?: throw IllegalStateException("Request or profile not set!") diff --git a/kvision-modules/kvision-server-jooby/src/main/kotlin/pl/treksoft/kvision/remote/SpringServiceManager.kt b/kvision-modules/kvision-server-jooby/src/main/kotlin/pl/treksoft/kvision/remote/SpringServiceManager.kt index 462b3777..5b566423 100644 --- a/kvision-modules/kvision-server-jooby/src/main/kotlin/pl/treksoft/kvision/remote/SpringServiceManager.kt +++ b/kvision-modules/kvision-server-jooby/src/main/kotlin/pl/treksoft/kvision/remote/SpringServiceManager.kt @@ -21,7 +21,6 @@ */ package pl.treksoft.kvision.remote -import kotlinx.coroutines.Deferred import kotlin.reflect.KClass /** @@ -36,7 +35,7 @@ actual open class SpringServiceManager<T : Any> actual constructor(val serviceCl * @param method a HTTP method */ protected actual inline fun <reified RET> bind( - noinline function: T.() -> Deferred<RET>, + noinline function: suspend T.() -> RET, route: String?, method: RpcHttpMethod ) { @@ -50,7 +49,7 @@ actual open class SpringServiceManager<T : Any> actual constructor(val serviceCl * @param method a HTTP method */ protected actual inline fun <reified PAR, reified RET> bind( - noinline function: T.(PAR) -> Deferred<RET>, + noinline function: suspend T.(PAR) -> RET, route: String?, method: RpcHttpMethod ) { @@ -64,7 +63,7 @@ actual open class SpringServiceManager<T : Any> actual constructor(val serviceCl * @param method a HTTP method */ protected actual inline fun <reified PAR1, reified PAR2, reified RET> bind( - noinline function: T.(PAR1, PAR2) -> Deferred<RET>, + noinline function: suspend T.(PAR1, PAR2) -> RET, route: String?, method: RpcHttpMethod ) { @@ -78,7 +77,7 @@ actual open class SpringServiceManager<T : Any> actual constructor(val serviceCl * @param method a HTTP method */ protected actual inline fun <reified PAR1, reified PAR2, reified PAR3, reified RET> bind( - noinline function: T.(PAR1, PAR2, PAR3) -> Deferred<RET>, + noinline function: suspend T.(PAR1, PAR2, PAR3) -> RET, route: String?, method: RpcHttpMethod ) { @@ -92,7 +91,7 @@ actual open class SpringServiceManager<T : Any> actual constructor(val serviceCl * @param method a HTTP method */ protected actual inline fun <reified PAR1, reified PAR2, reified PAR3, reified PAR4, reified RET> bind( - noinline function: T.(PAR1, PAR2, PAR3, PAR4) -> Deferred<RET>, + noinline function: suspend T.(PAR1, PAR2, PAR3, PAR4) -> RET, route: String?, method: RpcHttpMethod ) { @@ -105,8 +104,9 @@ actual open class SpringServiceManager<T : Any> actual constructor(val serviceCl * @param route a route * @param method a HTTP method */ - protected actual inline fun <reified PAR1, reified PAR2, reified PAR3, reified PAR4, reified PAR5, reified RET> bind( - noinline function: T.(PAR1, PAR2, PAR3, PAR4, PAR5) -> Deferred<RET>, + protected actual inline fun <reified PAR1, reified PAR2, reified PAR3, + reified PAR4, reified PAR5, reified RET> bind( + noinline function: suspend T.(PAR1, PAR2, PAR3, PAR4, PAR5) -> RET, route: String?, method: RpcHttpMethod ) { diff --git a/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/JoobyServiceManager.kt b/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/JoobyServiceManager.kt index 75410e07..422c97ba 100644 --- a/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/JoobyServiceManager.kt +++ b/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/JoobyServiceManager.kt @@ -21,8 +21,6 @@ */ package pl.treksoft.kvision.remote -import kotlinx.coroutines.Deferred - /** * Multiplatform service manager for Jooby. * Not to be used in this module. @@ -35,7 +33,7 @@ actual open class JoobyServiceManager<T : Any> actual constructor(val service: T * @param method a HTTP method */ protected actual inline fun <reified RET> bind( - noinline function: T.(Request?) -> Deferred<RET>, + noinline function: suspend T.(Request?) -> RET, route: String?, method: RpcHttpMethod ) { @@ -49,7 +47,7 @@ actual open class JoobyServiceManager<T : Any> actual constructor(val service: T * @param method a HTTP method */ protected actual inline fun <reified PAR, reified RET> bind( - noinline function: T.(PAR, Request?) -> Deferred<RET>, + noinline function: suspend T.(PAR, Request?) -> RET, route: String?, method: RpcHttpMethod ) { @@ -63,7 +61,7 @@ actual open class JoobyServiceManager<T : Any> actual constructor(val service: T * @param method a HTTP method */ protected actual inline fun <reified PAR1, reified PAR2, reified RET> bind( - noinline function: T.(PAR1, PAR2, Request?) -> Deferred<RET>, + noinline function: suspend T.(PAR1, PAR2, Request?) -> RET, route: String?, method: RpcHttpMethod ) { @@ -77,7 +75,7 @@ actual open class JoobyServiceManager<T : Any> actual constructor(val service: T * @param method a HTTP method */ protected actual inline fun <reified PAR1, reified PAR2, reified PAR3, reified RET> bind( - noinline function: T.(PAR1, PAR2, PAR3, Request?) -> Deferred<RET>, + noinline function: suspend T.(PAR1, PAR2, PAR3, Request?) -> RET, route: String?, method: RpcHttpMethod ) { @@ -91,7 +89,7 @@ actual open class JoobyServiceManager<T : Any> actual constructor(val service: T * @param method a HTTP method */ protected actual inline fun <reified PAR1, reified PAR2, reified PAR3, reified PAR4, reified RET> bind( - noinline function: T.(PAR1, PAR2, PAR3, PAR4, Request?) -> Deferred<RET>, + noinline function: suspend T.(PAR1, PAR2, PAR3, PAR4, Request?) -> RET, route: String?, method: RpcHttpMethod ) { @@ -104,8 +102,9 @@ actual open class JoobyServiceManager<T : Any> actual constructor(val service: T * @param route a route * @param method a HTTP method */ - protected actual inline fun <reified PAR1, reified PAR2, reified PAR3, reified PAR4, reified PAR5, reified RET> bind( - noinline function: T.(PAR1, PAR2, PAR3, PAR4, PAR5, Request?) -> Deferred<RET>, + protected actual inline fun <reified PAR1, reified PAR2, reified PAR3, + reified PAR4, reified PAR5, reified RET> bind( + noinline function: suspend T.(PAR1, PAR2, PAR3, PAR4, PAR5, Request?) -> RET, route: String?, method: RpcHttpMethod ) { diff --git a/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/KVServer.kt b/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/KVServer.kt index 11b848bf..f2e3e951 100644 --- a/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/KVServer.kt +++ b/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/KVServer.kt @@ -21,8 +21,6 @@ */ package pl.treksoft.kvision.remote -import kotlinx.coroutines.Deferred -import kotlinx.coroutines.GlobalScope import org.pac4j.core.context.J2EContext import org.pac4j.core.context.session.J2ESessionStore import org.pac4j.core.profile.CommonProfile @@ -48,17 +46,10 @@ actual typealias Request = HttpServletRequest actual typealias Profile = CommonProfile /** - * A helper extension function for asynchronous processing. + * A helper extension function for processing with authenticated user profile. */ -fun <RESP> async(block: () -> RESP): Deferred<RESP> = - GlobalScope.coroutinesAsync { - block() - } - -/** - * A helper extension function for asynchronous processing with user profile. - */ -fun <RESP> asyncAuth(block: (Profile) -> RESP): Deferred<RESP> { +@Suppress("TooGenericExceptionCaught") +fun <RESP> withProfile(block: (Profile) -> RESP): RESP { val profile = try { val requestAttributes = (RequestContextHolder.getRequestAttributes() as ServletRequestAttributes) val req = requestAttributes.request @@ -68,8 +59,6 @@ fun <RESP> asyncAuth(block: (Profile) -> RESP): Deferred<RESP> { null } return profile?.let { - GlobalScope.coroutinesAsync { - block(it) - } + block(it) } ?: throw IllegalStateException("Profile not set!") } diff --git a/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/SpringServiceManager.kt b/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/SpringServiceManager.kt index 1baa856e..a241842c 100644 --- a/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/SpringServiceManager.kt +++ b/kvision-modules/kvision-server-spring-boot/src/main/kotlin/pl/treksoft/kvision/remote/SpringServiceManager.kt @@ -22,8 +22,10 @@ package pl.treksoft.kvision.remote import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper -import kotlinx.coroutines.Deferred -import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.CoroutineStart +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.launch import org.slf4j.Logger import org.slf4j.LoggerFactory import java.text.SimpleDateFormat @@ -33,6 +35,7 @@ import kotlin.reflect.KClass /** * Multiplatform service manager for Spring Boot. */ +@UseExperimental(ExperimentalCoroutinesApi::class) actual open class SpringServiceManager<T : Any> actual constructor(val serviceClass: KClass<T>) : ServiceManager { companion object { @@ -57,33 +60,35 @@ actual open class SpringServiceManager<T : Any> actual constructor(val serviceCl */ @Suppress("TooGenericExceptionCaught") protected actual inline fun <reified RET> bind( - noinline function: T.() -> Deferred<RET>, + noinline function: suspend T.() -> RET, route: String?, method: RpcHttpMethod ) { val routeDef = route ?: "route${this::class.simpleName}${counter++}" addRoute(method, "/kv/$routeDef") { req, res -> val service = SpringContext.getBean(serviceClass.java) val jsonRpcRequest = mapper.readValue(req.inputStream, JsonRpcRequest::class.java) - try { - val result = runBlocking { function.invoke(service).await() } - res.writeJSON( - mapper.writeValueAsString( - JsonRpcResponse( - id = jsonRpcRequest.id, - result = mapper.writeValueAsString(result) + GlobalScope.launch(start = CoroutineStart.UNDISPATCHED) { + try { + val result = function.invoke(service) + res.writeJSON( + mapper.writeValueAsString( + JsonRpcResponse( + id = jsonRpcRequest.id, + result = mapper.writeValueAsString(result) + ) ) ) - ) - } catch (e: Exception) { - LOG.error(e.message, e) - res.writeJSON( - mapper.writeValueAsString( - JsonRpcResponse( - id = jsonRpcRequest.id, - error = e.message ?: "Error" + } catch (e: Exception) { + LOG.error(e.message, e) + res.writeJSON( + mapper.writeValueAsString( + JsonRpcResponse( + id = jsonRpcRequest.id, + error = e.message ?: "Error" + ) ) ) - ) + } } } } @@ -96,7 +101,7 @@ actual open class SpringServiceManager<T : Any> actual constructor(val serviceCl */ @Suppress("TooGenericExceptionCaught") protected actual inline fun <reified PAR, reified RET> bind( - noinline function: T.(PAR) -> Deferred<RET>, + noinline function: suspend T.(PAR) -> RET, route: String?, method: RpcHttpMethod ) { val routeDef = route ?: "route${this::class.simpleName}${counter++}" @@ -105,26 +110,28 @@ actual open class SpringServiceManager<T : Any> actual constructor(val serviceCl val jsonRpcRequest = mapper.readValue(req.inputStream, JsonRpcRequest::class.java) if (jsonRpcRequest.params.size == 1) { val param = getParameter<PAR>(jsonRpcRequest.params[0]) - try { - val result = runBlocking { function.invoke(service, param).await() } - res.writeJSON( - mapper.writeValueAsString( - JsonRpcResponse( - id = jsonRpcRequest.id, - result = mapper.writeValueAsString(result) + GlobalScope.launch(start = CoroutineStart.UNDISPATCHED) { + try { + val result = function.invoke(service, param) + res.writeJSON( + mapper.writeValueAsString( + JsonRpcResponse( + id = jsonRpcRequest.id, + result = mapper.writeValueAsString(result) + ) ) ) - ) - } catch (e: Exception) { - LOG.error(e.message, e) - res.writeJSON( - mapper.writeValueAsString( - JsonRpcResponse( - id = jsonRpcRequest.id, - error = e.message ?: "Error" + } catch (e: Exception) { + LOG.error(e.message, e) + res.writeJSON( + mapper.writeValueAsString( + JsonRpcResponse( + id = jsonRpcRequest.id, + error = e.message ?: "Error" + ) ) ) - ) + } } } else { res.writeJSON( @@ -147,7 +154,7 @@ actual open class SpringServiceManager<T : Any> actual constructor(val serviceCl */ @Suppress("TooGenericExceptionCaught") protected actual inline fun <reified PAR1, reified PAR2, reified RET> bind( - noinline function: T.(PAR1, PAR2) -> Deferred<RET>, + noinline function: suspend T.(PAR1, PAR2) -> RET, route: String?, method: RpcHttpMethod ) { val routeDef = route ?: "route${this::class.simpleName}${counter++}" @@ -157,26 +164,28 @@ actual open class SpringServiceManager<T : Any> actual constructor(val serviceCl if (jsonRpcRequest.params.size == 2) { val param1 = getParameter<PAR1>(jsonRpcRequest.params[0]) val param2 = getParameter<PAR2>(jsonRpcRequest.params[1]) - try { - val result = runBlocking { function.invoke(service, param1, param2).await() } - res.writeJSON( - mapper.writeValueAsString( - JsonRpcResponse( - id = jsonRpcRequest.id, - result = mapper.writeValueAsString(result) + GlobalScope.launch(start = CoroutineStart.UNDISPATCHED) { + try { + val result = function.invoke(service, param1, param2) + res.writeJSON( + mapper.writeValueAsString( + JsonRpcResponse( + id = jsonRpcRequest.id, + result = mapper.writeValueAsString(result) + ) ) ) - ) - } catch (e: Exception) { - LOG.error(e.message, e) - res.writeJSON( - mapper.writeValueAsString( - JsonRpcResponse( - id = jsonRpcRequest.id, - error = e.message ?: "Error" + } catch (e: Exception) { + LOG.error(e.message, e) + res.writeJSON( + mapper.writeValueAsString( + JsonRpcResponse( + id = jsonRpcRequest.id, + error = e.message ?: "Error" + ) ) ) - ) + } } } else { res.writeJSON( @@ -199,7 +208,7 @@ actual open class SpringServiceManager<T : Any> actual constructor(val serviceCl */ @Suppress("TooGenericExceptionCaught") protected actual inline fun <reified PAR1, reified PAR2, reified PAR3, reified RET> bind( - noinline function: T.(PAR1, PAR2, PAR3) -> Deferred<RET>, + noinline function: suspend T.(PAR1, PAR2, PAR3) -> RET, route: String?, method: RpcHttpMethod ) { val routeDef = route ?: "route${this::class.simpleName}${counter++}" @@ -211,26 +220,28 @@ actual open class SpringServiceManager<T : Any> actual constructor(val serviceCl val param1 = getParameter<PAR1>(jsonRpcRequest.params[0]) val param2 = getParameter<PAR2>(jsonRpcRequest.params[1]) val param3 = getParameter<PAR3>(jsonRpcRequest.params[2]) - try { - val result = runBlocking { function.invoke(service, param1, param2, param3).await() } - res.writeJSON( - mapper.writeValueAsString( - JsonRpcResponse( - id = jsonRpcRequest.id, - result = mapper.writeValueAsString(result) + GlobalScope.launch(start = CoroutineStart.UNDISPATCHED) { + try { + val result = function.invoke(service, param1, param2, param3) + res.writeJSON( + mapper.writeValueAsString( + JsonRpcResponse( + id = jsonRpcRequest.id, + result = mapper.writeValueAsString(result) + ) ) ) - ) - } catch (e: Exception) { - LOG.error(e.message, e) - res.writeJSON( - mapper.writeValueAsString( - JsonRpcResponse( - id = jsonRpcRequest.id, - error = e.message ?: "Error" + } catch (e: Exception) { + LOG.error(e.message, e) + res.writeJSON( + mapper.writeValueAsString( + JsonRpcResponse( + id = jsonRpcRequest.id, + error = e.message ?: "Error" + ) ) ) - ) + } } } else { res.writeJSON( @@ -253,7 +264,7 @@ actual open class SpringServiceManager<T : Any> actual constructor(val serviceCl */ @Suppress("TooGenericExceptionCaught") protected actual inline fun <reified PAR1, reified PAR2, reified PAR3, reified PAR4, reified RET> bind( - noinline function: T.(PAR1, PAR2, PAR3, PAR4) -> Deferred<RET>, + noinline function: suspend T.(PAR1, PAR2, PAR3, PAR4) -> RET, route: String?, method: RpcHttpMethod ) { val routeDef = route ?: "route${this::class.simpleName}${counter++}" @@ -266,27 +277,28 @@ actual open class SpringServiceManager<T : Any> actual constructor(val serviceCl val param2 = getParameter<PAR2>(jsonRpcRequest.params[1]) val param3 = getParameter<PAR3>(jsonRpcRequest.params[2]) val param4 = getParameter<PAR4>(jsonRpcRequest.params[3]) - try { - val result = - runBlocking { function.invoke(service, param1, param2, param3, param4).await() } - res.writeJSON( - mapper.writeValueAsString( - JsonRpcResponse( - id = jsonRpcRequest.id, - result = mapper.writeValueAsString(result) + GlobalScope.launch(start = CoroutineStart.UNDISPATCHED) { + try { + val result = function.invoke(service, param1, param2, param3, param4) + res.writeJSON( + mapper.writeValueAsString( + JsonRpcResponse( + id = jsonRpcRequest.id, + result = mapper.writeValueAsString(result) + ) ) ) - ) - } catch (e: Exception) { - LOG.error(e.message, e) - res.writeJSON( - mapper.writeValueAsString( - JsonRpcResponse( - id = jsonRpcRequest.id, - error = e.message ?: "Error" + } catch (e: Exception) { + LOG.error(e.message, e) + res.writeJSON( + mapper.writeValueAsString( + JsonRpcResponse( + id = jsonRpcRequest.id, + error = e.message ?: "Error" + ) ) ) - ) + } } } else { res.writeJSON( @@ -310,7 +322,7 @@ actual open class SpringServiceManager<T : Any> actual constructor(val serviceCl @Suppress("TooGenericExceptionCaught") protected actual inline fun <reified PAR1, reified PAR2, reified PAR3, reified PAR4, reified PAR5, reified RET> bind( - noinline function: T.(PAR1, PAR2, PAR3, PAR4, PAR5) -> Deferred<RET>, + noinline function: suspend T.(PAR1, PAR2, PAR3, PAR4, PAR5) -> RET, route: String?, method: RpcHttpMethod ) { @@ -325,29 +337,28 @@ actual open class SpringServiceManager<T : Any> actual constructor(val serviceCl val param3 = getParameter<PAR3>(jsonRpcRequest.params[2]) val param4 = getParameter<PAR4>(jsonRpcRequest.params[3]) val param5 = getParameter<PAR5>(jsonRpcRequest.params[4]) - try { - val result = - runBlocking { - function.invoke(service, param1, param2, param3, param4, param5).await() - } - res.writeJSON( - mapper.writeValueAsString( - JsonRpcResponse( - id = jsonRpcRequest.id, - result = mapper.writeValueAsString(result) + GlobalScope.launch(start = CoroutineStart.UNDISPATCHED) { + try { + val result = function.invoke(service, param1, param2, param3, param4, param5) + res.writeJSON( + mapper.writeValueAsString( + JsonRpcResponse( + id = jsonRpcRequest.id, + result = mapper.writeValueAsString(result) + ) ) ) - ) - } catch (e: Exception) { - LOG.error(e.message, e) - res.writeJSON( - mapper.writeValueAsString( - JsonRpcResponse( - id = jsonRpcRequest.id, - error = e.message ?: "Error" + } catch (e: Exception) { + LOG.error(e.message, e) + res.writeJSON( + mapper.writeValueAsString( + JsonRpcResponse( + id = jsonRpcRequest.id, + error = e.message ?: "Error" + ) ) ) - ) + } } } else { res.writeJSON( diff --git a/src/main/kotlin/pl/treksoft/kvision/remote/JoobyRemoteAgent.kt b/src/main/kotlin/pl/treksoft/kvision/remote/JoobyRemoteAgent.kt index 30d2062d..318f77ea 100644 --- a/src/main/kotlin/pl/treksoft/kvision/remote/JoobyRemoteAgent.kt +++ b/src/main/kotlin/pl/treksoft/kvision/remote/JoobyRemoteAgent.kt @@ -21,7 +21,6 @@ */ package pl.treksoft.kvision.remote -import kotlinx.coroutines.Deferred import kotlinx.coroutines.asDeferred import kotlinx.serialization.ImplicitReflectionSerializer import kotlinx.serialization.list @@ -43,7 +42,7 @@ open class JoobyRemoteAgent<T : Any>(val serviceManager: JoobyServiceManager<T>) /** * Executes defined call to a remote web service. */ - inline fun <reified RET : Any, T> call(noinline function: T.(Request?) -> Deferred<RET>): Deferred<RET> { + suspend inline fun <reified RET : Any, T> call(noinline function: suspend T.(Request?) -> RET): RET { val (url, method) = serviceManager.getCalls()[function.toString()] ?: throw IllegalStateException("Function not specified!") return callAgent.jsonRpcCall(url, method = method).then { @@ -58,15 +57,15 @@ open class JoobyRemoteAgent<T : Any>(val serviceManager: JoobyServiceManager<T>) JSON.nonstrict.parse(RET::class.serializer(), it) } } - }.asDeferred() + }.asDeferred().await() } /** * Executes defined call to a remote web service. */ - inline fun <reified RET : Any, T> call( - noinline function: T.(Request?) -> Deferred<List<RET>> - ): Deferred<List<RET>> { + suspend inline fun <reified RET : Any, T> call( + noinline function: suspend T.(Request?) -> List<RET> + ): List<RET> { val (url, method) = serviceManager.getCalls()[function.toString()] ?: throw IllegalStateException("Function not specified!") return callAgent.jsonRpcCall(url, method = method).then { @@ -80,15 +79,15 @@ open class JoobyRemoteAgent<T : Any>(val serviceManager: JoobyServiceManager<T>) JSON.nonstrict.parse(RET::class.serializer().list, it) } } - }.asDeferred() + }.asDeferred().await() } /** * Executes defined call to a remote web service. */ - inline fun <reified PAR, reified RET : Any, T> call( - noinline function: T.(PAR, Request?) -> Deferred<RET>, p: PAR - ): Deferred<RET> { + suspend inline fun <reified PAR, reified RET : Any, T> call( + noinline function: suspend T.(PAR, Request?) -> RET, p: PAR + ): RET { val data = serialize(p) val (url, method) = serviceManager.getCalls()[function.toString()] ?: throw IllegalStateException("Function not specified!") @@ -104,15 +103,15 @@ open class JoobyRemoteAgent<T : Any>(val serviceManager: JoobyServiceManager<T>) JSON.nonstrict.parse(RET::class.serializer(), it) } } - }.asDeferred() + }.asDeferred().await() } /** * Executes defined call to a remote web service. */ - inline fun <reified PAR, reified RET : Any, T> call( - noinline function: T.(PAR, Request?) -> Deferred<List<RET>>, p: PAR - ): Deferred<List<RET>> { + suspend inline fun <reified PAR, reified RET : Any, T> call( + noinline function: suspend T.(PAR, Request?) -> List<RET>, p: PAR + ): List<RET> { val data = serialize(p) val (url, method) = serviceManager.getCalls()[function.toString()] ?: throw IllegalStateException("Function not specified!") @@ -127,15 +126,15 @@ open class JoobyRemoteAgent<T : Any>(val serviceManager: JoobyServiceManager<T>) JSON.nonstrict.parse(RET::class.serializer().list, it) } } - }.asDeferred() + }.asDeferred().await() } /** * Executes defined call to a remote web service. */ - inline fun <reified PAR1, reified PAR2, reified RET : Any, T> call( - noinline function: T.(PAR1, PAR2, Request?) -> Deferred<RET>, p1: PAR1, p2: PAR2 - ): Deferred<RET> { + suspend inline fun <reified PAR1, reified PAR2, reified RET : Any, T> call( + noinline function: suspend T.(PAR1, PAR2, Request?) -> RET, p1: PAR1, p2: PAR2 + ): RET { val data1 = serialize(p1) val data2 = serialize(p2) val (url, method) = @@ -152,15 +151,15 @@ open class JoobyRemoteAgent<T : Any>(val serviceManager: JoobyServiceManager<T>) JSON.nonstrict.parse(RET::class.serializer(), it) } } - }.asDeferred() + }.asDeferred().await() } /** * Executes defined call to a remote web service. */ - inline fun <reified PAR1, reified PAR2, reified RET : Any, T> call( - noinline function: T.(PAR1, PAR2, Request?) -> Deferred<List<RET>>, p1: PAR1, p2: PAR2 - ): Deferred<List<RET>> { + suspend inline fun <reified PAR1, reified PAR2, reified RET : Any, T> call( + noinline function: suspend T.(PAR1, PAR2, Request?) -> List<RET>, p1: PAR1, p2: PAR2 + ): List<RET> { val data1 = serialize(p1) val data2 = serialize(p2) val (url, method) = @@ -176,15 +175,15 @@ open class JoobyRemoteAgent<T : Any>(val serviceManager: JoobyServiceManager<T>) JSON.nonstrict.parse(RET::class.serializer().list, it) } } - }.asDeferred() + }.asDeferred().await() } /** * Executes defined call to a remote web service. */ - inline fun <reified PAR1, reified PAR2, reified PAR3, reified RET : Any, T> call( - noinline function: T.(PAR1, PAR2, PAR3, Request?) -> Deferred<RET>, p1: PAR1, p2: PAR2, p3: PAR3 - ): Deferred<RET> { + suspend inline fun <reified PAR1, reified PAR2, reified PAR3, reified RET : Any, T> call( + noinline function: suspend T.(PAR1, PAR2, PAR3, Request?) -> RET, p1: PAR1, p2: PAR2, p3: PAR3 + ): RET { val data1 = serialize(p1) val data2 = serialize(p2) val data3 = serialize(p3) @@ -202,15 +201,15 @@ open class JoobyRemoteAgent<T : Any>(val serviceManager: JoobyServiceManager<T>) JSON.nonstrict.parse(RET::class.serializer(), it) } } - }.asDeferred() + }.asDeferred().await() } /** * Executes defined call to a remote web service. */ - inline fun <reified PAR1, reified PAR2, reified PAR3, reified RET : Any, T> call( - noinline function: T.(PAR1, PAR2, PAR3, Request?) -> Deferred<List<RET>>, p1: PAR1, p2: PAR2, p3: PAR3 - ): Deferred<List<RET>> { + suspend inline fun <reified PAR1, reified PAR2, reified PAR3, reified RET : Any, T> call( + noinline function: suspend T.(PAR1, PAR2, PAR3, Request?) -> List<RET>, p1: PAR1, p2: PAR2, p3: PAR3 + ): List<RET> { val data1 = serialize(p1) val data2 = serialize(p2) val data3 = serialize(p3) @@ -227,15 +226,15 @@ open class JoobyRemoteAgent<T : Any>(val serviceManager: JoobyServiceManager<T>) JSON.nonstrict.parse(RET::class.serializer().list, it) } } - }.asDeferred() + }.asDeferred().await() } /** * Executes defined call to a remote web service. */ - inline fun <reified PAR1, reified PAR2, reified PAR3, reified PAR4, reified RET : Any, T> call( - noinline function: T.(PAR1, PAR2, PAR3, PAR4, Request?) -> Deferred<RET>, p1: PAR1, p2: PAR2, p3: PAR3, p4: PAR4 - ): Deferred<RET> { + suspend inline fun <reified PAR1, reified PAR2, reified PAR3, reified PAR4, reified RET : Any, T> call( + noinline function: suspend T.(PAR1, PAR2, PAR3, PAR4, Request?) -> RET, p1: PAR1, p2: PAR2, p3: PAR3, p4: PAR4 + ): RET { val data1 = serialize(p1) val data2 = serialize(p2) val data3 = serialize(p3) @@ -254,19 +253,19 @@ open class JoobyRemoteAgent<T : Any>(val serviceManager: JoobyServiceManager<T>) JSON.nonstrict.parse(RET::class.serializer(), it) } } - }.asDeferred() + }.asDeferred().await() } /** * Executes defined call to a remote web service. */ - inline fun <reified PAR1, reified PAR2, reified PAR3, reified PAR4, reified RET : Any, T> call( - noinline function: T.(PAR1, PAR2, PAR3, PAR4, Request?) -> Deferred<List<RET>>, + suspend inline fun <reified PAR1, reified PAR2, reified PAR3, reified PAR4, reified RET : Any, T> call( + noinline function: suspend T.(PAR1, PAR2, PAR3, PAR4, Request?) -> List<RET>, p1: PAR1, p2: PAR2, p3: PAR3, p4: PAR4 - ): Deferred<List<RET>> { + ): List<RET> { val data1 = serialize(p1) val data2 = serialize(p2) val data3 = serialize(p3) @@ -284,22 +283,22 @@ open class JoobyRemoteAgent<T : Any>(val serviceManager: JoobyServiceManager<T>) JSON.nonstrict.parse(RET::class.serializer().list, it) } } - }.asDeferred() + }.asDeferred().await() } /** * Executes defined call to a remote web service. */ @Suppress("LongParameterList") - inline fun <reified PAR1, reified PAR2, reified PAR3, reified PAR4, reified PAR5, + suspend inline fun <reified PAR1, reified PAR2, reified PAR3, reified PAR4, reified PAR5, reified RET : Any, T> call( - noinline function: T.(PAR1, PAR2, PAR3, PAR4, PAR5, Request?) -> Deferred<RET>, + noinline function: suspend T.(PAR1, PAR2, PAR3, PAR4, PAR5, Request?) -> RET, p1: PAR1, p2: PAR2, p3: PAR3, p4: PAR4, p5: PAR5 - ): Deferred<RET> { + ): RET { val data1 = serialize(p1) val data2 = serialize(p2) val data3 = serialize(p3) @@ -319,22 +318,22 @@ open class JoobyRemoteAgent<T : Any>(val serviceManager: JoobyServiceManager<T>) JSON.nonstrict.parse(RET::class.serializer(), it) } } - }.asDeferred() + }.asDeferred().await() } /** * Executes defined call to a remote web service. */ @Suppress("LongParameterList") - inline fun <reified PAR1, reified PAR2, reified PAR3, reified PAR4, reified PAR5, + suspend inline fun <reified PAR1, reified PAR2, reified PAR3, reified PAR4, reified PAR5, reified RET : Any, T> call( - noinline function: T.(PAR1, PAR2, PAR3, PAR4, PAR5, Request?) -> Deferred<List<RET>>, + noinline function: suspend T.(PAR1, PAR2, PAR3, PAR4, PAR5, Request?) -> List<RET>, p1: PAR1, p2: PAR2, p3: PAR3, p4: PAR4, p5: PAR5 - ): Deferred<List<RET>> { + ): List<RET> { val data1 = serialize(p1) val data2 = serialize(p2) val data3 = serialize(p3) @@ -353,7 +352,7 @@ open class JoobyRemoteAgent<T : Any>(val serviceManager: JoobyServiceManager<T>) JSON.nonstrict.parse(RET::class.serializer().list, it) } } - }.asDeferred() + }.asDeferred().await() } diff --git a/src/main/kotlin/pl/treksoft/kvision/remote/JoobyServiceManager.kt b/src/main/kotlin/pl/treksoft/kvision/remote/JoobyServiceManager.kt index c9d8ba25..0d3515a1 100644 --- a/src/main/kotlin/pl/treksoft/kvision/remote/JoobyServiceManager.kt +++ b/src/main/kotlin/pl/treksoft/kvision/remote/JoobyServiceManager.kt @@ -21,8 +21,6 @@ */ package pl.treksoft.kvision.remote -import kotlinx.coroutines.Deferred - /** * Multiplatform service manager for Jooby. */ @@ -38,7 +36,7 @@ actual open class JoobyServiceManager<T : Any> actual constructor(service: T) : * @param method a HTTP method */ protected actual inline fun <reified RET> bind( - noinline function: T.(Request?) -> Deferred<RET>, + noinline function: suspend T.(Request?) -> RET, route: String?, method: RpcHttpMethod ) { val routeDef = route ?: "route${this::class.simpleName}${counter++}" @@ -52,7 +50,7 @@ actual open class JoobyServiceManager<T : Any> actual constructor(service: T) : * @param method a HTTP method */ protected actual inline fun <reified PAR, reified RET> bind( - noinline function: T.(PAR, Request?) -> Deferred<RET>, + noinline function: suspend T.(PAR, Request?) -> RET, route: String?, method: RpcHttpMethod ) { val routeDef = route ?: "route${this::class.simpleName}${counter++}" @@ -66,7 +64,7 @@ actual open class JoobyServiceManager<T : Any> actual constructor(service: T) : * @param method a HTTP method */ protected actual inline fun <reified PAR1, reified PAR2, reified RET> bind( - noinline function: T.(PAR1, PAR2, Request?) -> Deferred<RET>, + noinline function: suspend T.(PAR1, PAR2, Request?) -> RET, route: String?, method: RpcHttpMethod ) { val routeDef = route ?: "route${this::class.simpleName}${counter++}" @@ -80,7 +78,7 @@ actual open class JoobyServiceManager<T : Any> actual constructor(service: T) : * @param method a HTTP method */ protected actual inline fun <reified PAR1, reified PAR2, reified PAR3, reified RET> bind( - noinline function: T.(PAR1, PAR2, PAR3, Request?) -> Deferred<RET>, + noinline function: suspend T.(PAR1, PAR2, PAR3, Request?) -> RET, route: String?, method: RpcHttpMethod ) { val routeDef = route ?: "route${this::class.simpleName}${counter++}" @@ -94,7 +92,7 @@ actual open class JoobyServiceManager<T : Any> actual constructor(service: T) : * @param method a HTTP method */ protected actual inline fun <reified PAR1, reified PAR2, reified PAR3, reified PAR4, reified RET> bind( - noinline function: T.(PAR1, PAR2, PAR3, PAR4, Request?) -> Deferred<RET>, + noinline function: suspend T.(PAR1, PAR2, PAR3, PAR4, Request?) -> RET, route: String?, method: RpcHttpMethod ) { val routeDef = route ?: "route${this::class.simpleName}${counter++}" @@ -109,7 +107,7 @@ actual open class JoobyServiceManager<T : Any> actual constructor(service: T) : */ protected actual inline fun <reified PAR1, reified PAR2, reified PAR3, reified PAR4, reified PAR5, reified RET> bind( - noinline function: T.(PAR1, PAR2, PAR3, PAR4, PAR5, Request?) -> Deferred<RET>, + noinline function: suspend T.(PAR1, PAR2, PAR3, PAR4, PAR5, Request?) -> RET, route: String?, method: RpcHttpMethod ) { diff --git a/src/main/kotlin/pl/treksoft/kvision/remote/Security.kt b/src/main/kotlin/pl/treksoft/kvision/remote/Security.kt index bf77a06b..b485e17d 100644 --- a/src/main/kotlin/pl/treksoft/kvision/remote/Security.kt +++ b/src/main/kotlin/pl/treksoft/kvision/remote/Security.kt @@ -21,7 +21,6 @@ */ package pl.treksoft.kvision.remote -import kotlinx.coroutines.Deferred import kotlinx.coroutines.asDeferred import kotlinx.serialization.Serializable import pl.treksoft.kvision.utils.obj @@ -47,12 +46,12 @@ class LoginService { * Login with Pac4j FormClient. * @param credentials username and password credentials */ - fun login(credentials: Credentials?): Deferred<Boolean> = + suspend fun login(credentials: Credentials?): Boolean = if (credentials?.username != null) { loginAgent.remoteCall("callback?client_name=FormClient", obj { this.username = credentials.username this.password = credentials.password - }, HttpMethod.POST, "application/x-www-form-urlencoded").then { _: dynamic -> true }.asDeferred() + }, HttpMethod.POST, "application/x-www-form-urlencoded").then { _: dynamic -> true }.asDeferred().await() } else { throw SecurityException("Credentials cannot be empty") } diff --git a/src/main/kotlin/pl/treksoft/kvision/remote/SpringRemoteAgent.kt b/src/main/kotlin/pl/treksoft/kvision/remote/SpringRemoteAgent.kt index f329d10e..fea16b99 100644 --- a/src/main/kotlin/pl/treksoft/kvision/remote/SpringRemoteAgent.kt +++ b/src/main/kotlin/pl/treksoft/kvision/remote/SpringRemoteAgent.kt @@ -21,7 +21,6 @@ */ package pl.treksoft.kvision.remote -import kotlinx.coroutines.Deferred import kotlinx.coroutines.asDeferred import kotlinx.serialization.ImplicitReflectionSerializer import kotlinx.serialization.list @@ -43,7 +42,7 @@ open class SpringRemoteAgent<T : Any>(val serviceManager: SpringServiceManager<T /** * Executes defined call to a remote web service. */ - inline fun <reified RET : Any, T> call(noinline function: T.() -> Deferred<RET>): Deferred<RET> { + suspend inline fun <reified RET : Any, T> call(noinline function: suspend T.() -> RET): RET { val (url, method) = serviceManager.getCalls()[function.toString()] ?: throw IllegalStateException("Function not specified!") return callAgent.jsonRpcCall(url, method = method).then { @@ -58,15 +57,15 @@ open class SpringRemoteAgent<T : Any>(val serviceManager: SpringServiceManager<T JSON.nonstrict.parse(RET::class.serializer(), it) } } - }.asDeferred() + }.asDeferred().await() } /** * Executes defined call to a remote web service. */ - inline fun <reified RET : Any, T> call( - noinline function: T.() -> Deferred<List<RET>> - ): Deferred<List<RET>> { + suspend inline fun <reified RET : Any, T> call( + noinline function: suspend T.() -> List<RET> + ): List<RET> { val (url, method) = serviceManager.getCalls()[function.toString()] ?: throw IllegalStateException("Function not specified!") return callAgent.jsonRpcCall(url, method = method).then { @@ -80,15 +79,15 @@ open class SpringRemoteAgent<T : Any>(val serviceManager: SpringServiceManager<T JSON.nonstrict.parse(RET::class.serializer().list, it) } } - }.asDeferred() + }.asDeferred().await() } /** * Executes defined call to a remote web service. */ - inline fun <reified PAR, reified RET : Any, T> call( - noinline function: T.(PAR) -> Deferred<RET>, p: PAR - ): Deferred<RET> { + suspend inline fun <reified PAR, reified RET : Any, T> call( + noinline function: suspend T.(PAR) -> RET, p: PAR + ): RET { val data = serialize(p) val (url, method) = serviceManager.getCalls()[function.toString()] ?: throw IllegalStateException("Function not specified!") @@ -104,15 +103,15 @@ open class SpringRemoteAgent<T : Any>(val serviceManager: SpringServiceManager<T JSON.nonstrict.parse(RET::class.serializer(), it) } } - }.asDeferred() + }.asDeferred().await() } /** * Executes defined call to a remote web service. */ - inline fun <reified PAR, reified RET : Any, T> call( - noinline function: T.(PAR) -> Deferred<List<RET>>, p: PAR - ): Deferred<List<RET>> { + suspend inline fun <reified PAR, reified RET : Any, T> call( + noinline function: suspend T.(PAR) -> List<RET>, p: PAR + ): List<RET> { val data = serialize(p) val (url, method) = serviceManager.getCalls()[function.toString()] ?: throw IllegalStateException("Function not specified!") @@ -127,15 +126,15 @@ open class SpringRemoteAgent<T : Any>(val serviceManager: SpringServiceManager<T JSON.nonstrict.parse(RET::class.serializer().list, it) } } - }.asDeferred() + }.asDeferred().await() } /** * Executes defined call to a remote web service. */ - inline fun <reified PAR1, reified PAR2, reified RET : Any, T> call( - noinline function: T.(PAR1, PAR2) -> Deferred<RET>, p1: PAR1, p2: PAR2 - ): Deferred<RET> { + suspend inline fun <reified PAR1, reified PAR2, reified RET : Any, T> call( + noinline function: suspend T.(PAR1, PAR2) -> RET, p1: PAR1, p2: PAR2 + ): RET { val data1 = serialize(p1) val data2 = serialize(p2) val (url, method) = @@ -152,15 +151,15 @@ open class SpringRemoteAgent<T : Any>(val serviceManager: SpringServiceManager<T JSON.nonstrict.parse(RET::class.serializer(), it) } } - }.asDeferred() + }.asDeferred().await() } /** * Executes defined call to a remote web service. */ - inline fun <reified PAR1, reified PAR2, reified RET : Any, T> call( - noinline function: T.(PAR1, PAR2) -> Deferred<List<RET>>, p1: PAR1, p2: PAR2 - ): Deferred<List<RET>> { + suspend inline fun <reified PAR1, reified PAR2, reified RET : Any, T> call( + noinline function: suspend T.(PAR1, PAR2) -> List<RET>, p1: PAR1, p2: PAR2 + ): List<RET> { val data1 = serialize(p1) val data2 = serialize(p2) val (url, method) = @@ -176,15 +175,15 @@ open class SpringRemoteAgent<T : Any>(val serviceManager: SpringServiceManager<T JSON.nonstrict.parse(RET::class.serializer().list, it) } } - }.asDeferred() + }.asDeferred().await() } /** * Executes defined call to a remote web service. */ - inline fun <reified PAR1, reified PAR2, reified PAR3, reified RET : Any, T> call( - noinline function: T.(PAR1, PAR2, PAR3) -> Deferred<RET>, p1: PAR1, p2: PAR2, p3: PAR3 - ): Deferred<RET> { + suspend inline fun <reified PAR1, reified PAR2, reified PAR3, reified RET : Any, T> call( + noinline function: suspend T.(PAR1, PAR2, PAR3) -> RET, p1: PAR1, p2: PAR2, p3: PAR3 + ): RET { val data1 = serialize(p1) val data2 = serialize(p2) val data3 = serialize(p3) @@ -202,15 +201,15 @@ open class SpringRemoteAgent<T : Any>(val serviceManager: SpringServiceManager<T JSON.nonstrict.parse(RET::class.serializer(), it) } } - }.asDeferred() + }.asDeferred().await() } /** * Executes defined call to a remote web service. */ - inline fun <reified PAR1, reified PAR2, reified PAR3, reified RET : Any, T> call( - noinline function: T.(PAR1, PAR2, PAR3) -> Deferred<List<RET>>, p1: PAR1, p2: PAR2, p3: PAR3 - ): Deferred<List<RET>> { + suspend inline fun <reified PAR1, reified PAR2, reified PAR3, reified RET : Any, T> call( + noinline function: suspend T.(PAR1, PAR2, PAR3) -> List<RET>, p1: PAR1, p2: PAR2, p3: PAR3 + ): List<RET> { val data1 = serialize(p1) val data2 = serialize(p2) val data3 = serialize(p3) @@ -227,15 +226,15 @@ open class SpringRemoteAgent<T : Any>(val serviceManager: SpringServiceManager<T JSON.nonstrict.parse(RET::class.serializer().list, it) } } - }.asDeferred() + }.asDeferred().await() } /** * Executes defined call to a remote web service. */ - inline fun <reified PAR1, reified PAR2, reified PAR3, reified PAR4, reified RET : Any, T> call( - noinline function: T.(PAR1, PAR2, PAR3, PAR4) -> Deferred<RET>, p1: PAR1, p2: PAR2, p3: PAR3, p4: PAR4 - ): Deferred<RET> { + suspend inline fun <reified PAR1, reified PAR2, reified PAR3, reified PAR4, reified RET : Any, T> call( + noinline function: suspend T.(PAR1, PAR2, PAR3, PAR4) -> RET, p1: PAR1, p2: PAR2, p3: PAR3, p4: PAR4 + ): RET { val data1 = serialize(p1) val data2 = serialize(p2) val data3 = serialize(p3) @@ -254,19 +253,19 @@ open class SpringRemoteAgent<T : Any>(val serviceManager: SpringServiceManager<T JSON.nonstrict.parse(RET::class.serializer(), it) } } - }.asDeferred() + }.asDeferred().await() } /** * Executes defined call to a remote web service. */ - inline fun <reified PAR1, reified PAR2, reified PAR3, reified PAR4, reified RET : Any, T> call( - noinline function: T.(PAR1, PAR2, PAR3, PAR4) -> Deferred<List<RET>>, + suspend inline fun <reified PAR1, reified PAR2, reified PAR3, reified PAR4, reified RET : Any, T> call( + noinline function: suspend T.(PAR1, PAR2, PAR3, PAR4) -> List<RET>, p1: PAR1, p2: PAR2, p3: PAR3, p4: PAR4 - ): Deferred<List<RET>> { + ): List<RET> { val data1 = serialize(p1) val data2 = serialize(p2) val data3 = serialize(p3) @@ -284,22 +283,22 @@ open class SpringRemoteAgent<T : Any>(val serviceManager: SpringServiceManager<T JSON.nonstrict.parse(RET::class.serializer().list, it) } } - }.asDeferred() + }.asDeferred().await() } /** * Executes defined call to a remote web service. */ @Suppress("LongParameterList") - inline fun <reified PAR1, reified PAR2, reified PAR3, reified PAR4, reified PAR5, + suspend inline fun <reified PAR1, reified PAR2, reified PAR3, reified PAR4, reified PAR5, reified RET : Any, T> call( - noinline function: T.(PAR1, PAR2, PAR3, PAR4, PAR5) -> Deferred<RET>, + noinline function: suspend T.(PAR1, PAR2, PAR3, PAR4, PAR5) -> RET, p1: PAR1, p2: PAR2, p3: PAR3, p4: PAR4, p5: PAR5 - ): Deferred<RET> { + ): RET { val data1 = serialize(p1) val data2 = serialize(p2) val data3 = serialize(p3) @@ -319,22 +318,22 @@ open class SpringRemoteAgent<T : Any>(val serviceManager: SpringServiceManager<T JSON.nonstrict.parse(RET::class.serializer(), it) } } - }.asDeferred() + }.asDeferred().await() } /** * Executes defined call to a remote web service. */ @Suppress("LongParameterList") - inline fun <reified PAR1, reified PAR2, reified PAR3, reified PAR4, reified PAR5, + suspend inline fun <reified PAR1, reified PAR2, reified PAR3, reified PAR4, reified PAR5, reified RET : Any, T> call( - noinline function: T.(PAR1, PAR2, PAR3, PAR4, PAR5) -> Deferred<List<RET>>, + noinline function: suspend T.(PAR1, PAR2, PAR3, PAR4, PAR5) -> List<RET>, p1: PAR1, p2: PAR2, p3: PAR3, p4: PAR4, p5: PAR5 - ): Deferred<List<RET>> { + ): List<RET> { val data1 = serialize(p1) val data2 = serialize(p2) val data3 = serialize(p3) @@ -353,7 +352,7 @@ open class SpringRemoteAgent<T : Any>(val serviceManager: SpringServiceManager<T JSON.nonstrict.parse(RET::class.serializer().list, it) } } - }.asDeferred() + }.asDeferred().await() } diff --git a/src/main/kotlin/pl/treksoft/kvision/remote/SpringServiceManager.kt b/src/main/kotlin/pl/treksoft/kvision/remote/SpringServiceManager.kt index 6b26da8e..524347d7 100644 --- a/src/main/kotlin/pl/treksoft/kvision/remote/SpringServiceManager.kt +++ b/src/main/kotlin/pl/treksoft/kvision/remote/SpringServiceManager.kt @@ -21,7 +21,6 @@ */ package pl.treksoft.kvision.remote -import kotlinx.coroutines.Deferred import kotlin.reflect.KClass /** @@ -39,7 +38,7 @@ actual open class SpringServiceManager<T : Any> actual constructor(serviceClass: * @param method a HTTP method */ protected actual inline fun <reified RET> bind( - noinline function: T.() -> Deferred<RET>, + noinline function: suspend T.() -> RET, route: String?, method: RpcHttpMethod ) { val routeDef = route ?: "route${this::class.simpleName}${counter++}" @@ -53,7 +52,7 @@ actual open class SpringServiceManager<T : Any> actual constructor(serviceClass: * @param method a HTTP method */ protected actual inline fun <reified PAR, reified RET> bind( - noinline function: T.(PAR) -> Deferred<RET>, + noinline function: suspend T.(PAR) -> RET, route: String?, method: RpcHttpMethod ) { val routeDef = route ?: "route${this::class.simpleName}${counter++}" @@ -67,7 +66,7 @@ actual open class SpringServiceManager<T : Any> actual constructor(serviceClass: * @param method a HTTP method */ protected actual inline fun <reified PAR1, reified PAR2, reified RET> bind( - noinline function: T.(PAR1, PAR2) -> Deferred<RET>, + noinline function: suspend T.(PAR1, PAR2) -> RET, route: String?, method: RpcHttpMethod ) { val routeDef = route ?: "route${this::class.simpleName}${counter++}" @@ -81,7 +80,7 @@ actual open class SpringServiceManager<T : Any> actual constructor(serviceClass: * @param method a HTTP method */ protected actual inline fun <reified PAR1, reified PAR2, reified PAR3, reified RET> bind( - noinline function: T.(PAR1, PAR2, PAR3) -> Deferred<RET>, + noinline function: suspend T.(PAR1, PAR2, PAR3) -> RET, route: String?, method: RpcHttpMethod ) { val routeDef = route ?: "route${this::class.simpleName}${counter++}" @@ -95,7 +94,7 @@ actual open class SpringServiceManager<T : Any> actual constructor(serviceClass: * @param method a HTTP method */ protected actual inline fun <reified PAR1, reified PAR2, reified PAR3, reified PAR4, reified RET> bind( - noinline function: T.(PAR1, PAR2, PAR3, PAR4) -> Deferred<RET>, + noinline function: suspend T.(PAR1, PAR2, PAR3, PAR4) -> RET, route: String?, method: RpcHttpMethod ) { val routeDef = route ?: "route${this::class.simpleName}${counter++}" @@ -110,7 +109,7 @@ actual open class SpringServiceManager<T : Any> actual constructor(serviceClass: */ protected actual inline fun <reified PAR1, reified PAR2, reified PAR3, reified PAR4, reified PAR5, reified RET> bind( - noinline function: T.(PAR1, PAR2, PAR3, PAR4, PAR5) -> Deferred<RET>, + noinline function: suspend T.(PAR1, PAR2, PAR3, PAR4, PAR5) -> RET, route: String?, method: RpcHttpMethod ) { |