Skip to content

Commit fe2c958

Browse files
committed
Added client APIs (no codegen)
1 parent 0a2661f commit fe2c958

File tree

3 files changed

+106
-5
lines changed

3 files changed

+106
-5
lines changed

grpc/grpc-core/src/commonMain/kotlin/kotlinx/rpc/grpc/GrpcClient.kt

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,24 @@
55
package kotlinx.rpc.grpc
66

77
import kotlinx.coroutines.CoroutineScope
8+
import kotlinx.coroutines.SupervisorJob
89
import kotlinx.coroutines.flow.Flow
910
import kotlinx.coroutines.flow.SharedFlow
1011
import kotlinx.coroutines.flow.StateFlow
12+
import kotlinx.coroutines.job
1113
import kotlinx.rpc.RPCCall
1214
import kotlinx.rpc.RPCClient
1315
import kotlinx.rpc.RPCField
1416
import kotlin.coroutines.CoroutineContext
1517

16-
public class GrpcClient : RPCClient {
17-
override val coroutineContext: CoroutineContext
18-
get() = TODO("Not yet implemented")
18+
public class GrpcClient(
19+
private val channel: ManagedChannel,
20+
) : RPCClient {
21+
override val coroutineContext: CoroutineContext = SupervisorJob()
1922

2023
override suspend fun <T> call(call: RPCCall): T {
21-
TODO("Not yet implemented")
24+
// todo perform call
25+
error("not implemented")
2226
}
2327

2428
override fun <T> registerPlainFlowField(serviceScope: CoroutineScope, field: RPCField): Flow<T> {
@@ -34,6 +38,24 @@ public class GrpcClient : RPCClient {
3438
}
3539

3640
override fun provideStubContext(serviceId: Long): CoroutineContext {
37-
TODO("Not yet implemented")
41+
// todo create lifetime hierarchy if possible
42+
return SupervisorJob(coroutineContext.job)
3843
}
3944
}
45+
46+
public fun grpcClient(
47+
name: String,
48+
port: Int,
49+
configure: ManagedChannelBuilder<*>.() -> Unit = {},
50+
): GrpcClient {
51+
val channel = ManagedChannelBuilder(name, port).apply(configure).buildChannel()
52+
return GrpcClient(channel)
53+
}
54+
55+
public fun grpcClient(
56+
target: String,
57+
configure: ManagedChannelBuilder<*>.() -> Unit = {},
58+
): GrpcClient {
59+
val channel = ManagedChannelBuilder(target).apply(configure).buildChannel()
60+
return GrpcClient(channel)
61+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
3+
*/
4+
5+
@file:Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING")
6+
7+
package kotlinx.rpc.grpc
8+
9+
import kotlin.time.Duration
10+
11+
public interface ManagedChannel {
12+
public val isShutdown: Boolean
13+
public val isTerminated: Boolean
14+
15+
public suspend fun awaitTermination(duration: Duration): Boolean
16+
17+
public fun shutdown(): ManagedChannel
18+
public fun shutdownNow(): ManagedChannel
19+
}
20+
21+
public expect abstract class ManagedChannelBuilder<T : io.grpc.ManagedChannelBuilder<T>>
22+
23+
public expect fun ManagedChannelBuilder(name: String, port: Int): ManagedChannelBuilder<*>
24+
public expect fun ManagedChannelBuilder(target: String): ManagedChannelBuilder<*>
25+
26+
public expect fun ManagedChannelBuilder<*>.buildChannel(): ManagedChannel
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
3+
*/
4+
5+
@file:Suppress("EXPECT_ACTUAL_CLASSIFIERS_ARE_IN_BETA_WARNING")
6+
7+
package kotlinx.rpc.grpc
8+
9+
import kotlinx.coroutines.Dispatchers
10+
import kotlinx.coroutines.withContext
11+
import kotlin.time.Duration
12+
13+
public actual typealias ManagedChannelBuilder<T> = io.grpc.ManagedChannelBuilder<T>
14+
15+
public actual fun ManagedChannelBuilder<*>.buildChannel(): ManagedChannel {
16+
return build().toKotlin()
17+
}
18+
19+
public actual fun ManagedChannelBuilder(name: String, port: Int): ManagedChannelBuilder<*> {
20+
return io.grpc.ManagedChannelBuilder.forAddress(name, port)
21+
}
22+
23+
public actual fun ManagedChannelBuilder(target: String): ManagedChannelBuilder<*> {
24+
return io.grpc.ManagedChannelBuilder.forTarget(target)
25+
}
26+
27+
public fun io.grpc.ManagedChannel.toKotlin(): ManagedChannel {
28+
return JvmManagedChannel(this)
29+
}
30+
31+
private class JvmManagedChannel(private val channel: io.grpc.ManagedChannel) : ManagedChannel {
32+
override val isShutdown: Boolean
33+
get() = channel.isShutdown
34+
35+
override val isTerminated: Boolean
36+
get() = channel.isTerminated
37+
38+
override suspend fun awaitTermination(duration: Duration): Boolean {
39+
return withContext(Dispatchers.IO) {
40+
channel.awaitTermination(duration.inWholeNanoseconds, java.util.concurrent.TimeUnit.NANOSECONDS)
41+
}
42+
}
43+
44+
override fun shutdown(): ManagedChannel {
45+
channel.shutdown()
46+
return this
47+
}
48+
49+
override fun shutdownNow(): ManagedChannel {
50+
channel.shutdownNow()
51+
return this
52+
}
53+
}

0 commit comments

Comments
 (0)