From 0bb67c093dc325232b37e32fb86cf1f7375550e8 Mon Sep 17 00:00:00 2001 From: Mihailov Date: Mon, 16 Mar 2020 14:33:20 +0300 Subject: [PATCH] Coroutine builder for service call --- coroutine-service-call/pom.xml | 40 +++++++++++ .../coroutine/ServicelCallBuilders.kt | 68 +++++++++++++++++++ hello-impl/pom.xml | 9 ++- .../hello/impl/KHelloServiceImpl.kt | 18 +++-- pom.xml | 16 ++++- stream-impl/pom.xml | 5 ++ .../stream/impl/KStreamServiceImpl.kt | 10 ++- 7 files changed, 146 insertions(+), 20 deletions(-) create mode 100644 coroutine-service-call/pom.xml create mode 100644 coroutine-service-call/src/main/kotlin/org/cakesolutions/coroutine/ServicelCallBuilders.kt diff --git a/coroutine-service-call/pom.xml b/coroutine-service-call/pom.xml new file mode 100644 index 0000000..9af825a --- /dev/null +++ b/coroutine-service-call/pom.xml @@ -0,0 +1,40 @@ + + + + lagomkotlin + org.cakesolutions + 1.0-SNAPSHOT + + 4.0.0 + + coroutine-service-call + + + + com.lightbend.lagom + lagom-javadsl-server_2.11 + + + org.jetbrains.kotlin + kotlin-stdlib + + + org.jetbrains.kotlinx + kotlinx-coroutines-core + + + org.jetbrains.kotlinx + kotlinx-coroutines-jdk8 + + + + + + kotlin-maven-plugin + org.jetbrains.kotlin + + + + diff --git a/coroutine-service-call/src/main/kotlin/org/cakesolutions/coroutine/ServicelCallBuilders.kt b/coroutine-service-call/src/main/kotlin/org/cakesolutions/coroutine/ServicelCallBuilders.kt new file mode 100644 index 0000000..8bde19d --- /dev/null +++ b/coroutine-service-call/src/main/kotlin/org/cakesolutions/coroutine/ServicelCallBuilders.kt @@ -0,0 +1,68 @@ +package org.cakesolutions.coroutine + +import com.lightbend.lagom.javadsl.api.ServiceCall +import com.lightbend.lagom.javadsl.api.transport.RequestHeader +import com.lightbend.lagom.javadsl.api.transport.ResponseHeader +import com.lightbend.lagom.javadsl.server.HeaderServiceCall +import com.lightbend.lagom.javadsl.server.ServerServiceCall +import kotlin.coroutines.CoroutineContext +import kotlin.coroutines.EmptyCoroutineContext +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.CoroutineStart +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.future.future + +/** + * @author Alex Mihailov {@literal }. + */ + +/** + * Starts new coroutine and returns its result as an implementation of [ServiceCall]. + * + * @param context additional to [CoroutineScope.coroutineContext] context of the coroutine. + * @param start coroutine start option. The default value is [CoroutineStart.DEFAULT]. + * @param block the coroutine code. + */ +fun serviceCall( + context: CoroutineContext = EmptyCoroutineContext, + start: CoroutineStart = CoroutineStart.DEFAULT, + block: suspend CoroutineScope.(request: Request) -> Response +) = ServiceCall { + CoroutineScope(Dispatchers.Unconfined).future(context, start) { + block(it) + } +} + +/** + * Starts new coroutine and returns its result as an implementation of [ServerServiceCall]. + * + * @param context additional to [CoroutineScope.coroutineContext] context of the coroutine. + * @param start coroutine start option. The default value is [CoroutineStart.DEFAULT]. + * @param block the coroutine code. + */ +fun serverServiceCall( + context: CoroutineContext = EmptyCoroutineContext, + start: CoroutineStart = CoroutineStart.DEFAULT, + block: suspend CoroutineScope.(request: Request) -> Response +) = ServerServiceCall { + CoroutineScope(Dispatchers.Unconfined).future(context, start) { + block(it) + } +} + +/** + * Starts new coroutine and returns its result as an implementation of [HeaderServiceCall]. + * + * @param context additional to [CoroutineScope.coroutineContext] context of the coroutine. + * @param start coroutine start option. The default value is [CoroutineStart.DEFAULT]. + * @param block the coroutine code. + */ +fun headerServiceCall( + context: CoroutineContext = EmptyCoroutineContext, + start: CoroutineStart = CoroutineStart.DEFAULT, + block: suspend CoroutineScope.(requestHeader: RequestHeader, request: Request) -> akka.japi.Pair +) = HeaderServiceCall { requestHeader, request -> + CoroutineScope(Dispatchers.Unconfined).future(context, start) { + block(requestHeader, request) + } +} diff --git a/hello-impl/pom.xml b/hello-impl/pom.xml index 83b9ee8..230545f 100644 --- a/hello-impl/pom.xml +++ b/hello-impl/pom.xml @@ -15,9 +15,14 @@ - org.cakesolutions + ${project.groupId} hello-api - 1.0-SNAPSHOT + ${project.version} + + + ${project.groupId} + coroutine-service-call + ${project.version} com.lightbend.lagom diff --git a/hello-impl/src/main/kotlin/org/cakesolutions/hello/impl/KHelloServiceImpl.kt b/hello-impl/src/main/kotlin/org/cakesolutions/hello/impl/KHelloServiceImpl.kt index ad16daa..005ac7c 100644 --- a/hello-impl/src/main/kotlin/org/cakesolutions/hello/impl/KHelloServiceImpl.kt +++ b/hello-impl/src/main/kotlin/org/cakesolutions/hello/impl/KHelloServiceImpl.kt @@ -4,6 +4,8 @@ import akka.Done import akka.NotUsed import com.lightbend.lagom.javadsl.api.ServiceCall import com.lightbend.lagom.javadsl.persistence.PersistentEntityRegistry +import kotlinx.coroutines.future.await +import org.cakesolutions.coroutine.serviceCall import org.cakesolutions.hello.api.KGreetingMessage import org.cakesolutions.hello.api.KHelloService import java.util.Optional @@ -16,17 +18,13 @@ class KHelloServiceImpl @Inject constructor(private val persistentEntityRegistry persistentEntityRegistry.register(KHelloEntity::class.java) } - override fun hello(id: String): ServiceCall { - return ServiceCall { - val ref = persistentEntityRegistry.refFor(KHelloEntity::class.java, id) - ref.ask(KHelloCommand.Hello(id, Optional.empty())) - } + override fun hello(id: String): ServiceCall = serviceCall { + val ref = persistentEntityRegistry.refFor(KHelloEntity::class.java, id) + ref.ask(KHelloCommand.Hello(id, Optional.empty())).await() } - override fun useGreeting(id: String): ServiceCall { - return ServiceCall { request -> - val ref = persistentEntityRegistry.refFor(KHelloEntity::class.java, id) - ref.ask(KHelloCommand.UserGreetingMessage(request.message)) - } + override fun useGreeting(id: String): ServiceCall = serviceCall { request -> + val ref = persistentEntityRegistry.refFor(KHelloEntity::class.java, id) + ref.ask(KHelloCommand.UserGreetingMessage(request.message)).await() } } \ No newline at end of file diff --git a/pom.xml b/pom.xml index 9a7f096..dd70dc2 100644 --- a/pom.xml +++ b/pom.xml @@ -16,6 +16,7 @@ stream-impl integration-tests cassandra-config + coroutine-service-call @@ -205,6 +206,16 @@ kotlin-reflect ${kotlin.version} + + org.jetbrains.kotlinx + kotlinx-coroutines-core + ${kotlin.coroutines.version} + + + org.jetbrains.kotlinx + kotlinx-coroutines-jdk8 + ${kotlin.coroutines.version} + @@ -215,9 +226,10 @@ 2.5.10 2.4.16 lagom10-conductr-bundle-lib_2.11 - 1.2.71 + 1.3.50 true - 1.2 + 1.3 1.8 + 1.3.2 diff --git a/stream-impl/pom.xml b/stream-impl/pom.xml index 30de7e4..876e6ea 100644 --- a/stream-impl/pom.xml +++ b/stream-impl/pom.xml @@ -24,6 +24,11 @@ hello-api ${project.version} + + ${project.groupId} + coroutine-service-call + ${project.version} + com.lightbend.lagom lagom-javadsl-server_2.11 diff --git a/stream-impl/src/main/kotlin/org/cakesolutions/stream/impl/KStreamServiceImpl.kt b/stream-impl/src/main/kotlin/org/cakesolutions/stream/impl/KStreamServiceImpl.kt index 78586a1..7c8d136 100644 --- a/stream-impl/src/main/kotlin/org/cakesolutions/stream/impl/KStreamServiceImpl.kt +++ b/stream-impl/src/main/kotlin/org/cakesolutions/stream/impl/KStreamServiceImpl.kt @@ -3,19 +3,17 @@ package org.cakesolutions.stream.impl import akka.NotUsed import akka.stream.javadsl.Source import com.lightbend.lagom.javadsl.api.ServiceCall +import org.cakesolutions.coroutine.serviceCall import org.cakesolutions.hello.api.KHelloService import org.cakesolutions.stream.api.KStreamService -import java.util.concurrent.CompletableFuture.completedFuture import javax.inject.Inject class KStreamServiceImpl @Inject constructor(private val helloService: KHelloService) : KStreamService { - override fun stream(): ServiceCall, Source> { - return ServiceCall { hellos -> - completedFuture(hellos.mapAsync(8){ name -> - helloService.hello(name)() - }) + override fun stream(): ServiceCall, Source> = serviceCall { hellos -> + hellos.mapAsync(8) { name -> + helloService.hello(name)() } } } \ No newline at end of file