All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.rouz.grpc.Adapters.kt Maven / Gradle / Ivy

There is a newer version: 0.1.4
Show newest version
package io.rouz.grpc

import io.grpc.Context
import io.grpc.stub.StreamObserver
import kotlin.coroutines.*
import kotlinx.coroutines.*
import kotlinx.coroutines.channels.*

class ManyToOneCall(
    private val request: StreamObserver,
    private val response: Deferred
) : StreamObserverSendAdapter(request),
    Deferred by response

class ManyToManyCall(
    private val request: StreamObserver,
    private val response: ReceiveChannel
) : StreamObserverSendAdapter(request),
    ReceiveChannel by response

open class StreamObserverSendAdapter(private val streamObserver: StreamObserver) {

    fun close(cause: Throwable? = null): Boolean {
        if (cause != null) {
            streamObserver.onError(cause)
        } else {
            streamObserver.onCompleted()
        }

        return true
    }

    fun send(element: E) {
        streamObserver.onNext(element)
    }
}

class ContinuationStreamObserver(
    private val continuation: Continuation
) : StreamObserver {

    override fun onNext(value: E) {
        continuation.resume(value)
    }

    override fun onError(t: Throwable) {
        continuation.resumeWithException(t)
    }

    override fun onCompleted() {}
}

class StreamObserverDeferred(
    private val deferred: CompletableDeferred = CompletableDeferred()
) : StreamObserver, Deferred by deferred {

    override fun onNext(value: E) {
        deferred.complete(value)
    }

    override fun onError(t: Throwable) {
        deferred.completeExceptionally(t)
    }

    override fun onCompleted() { /* nothing */
    }
}

class StreamObserverChannel(
    private val channel: Channel = Channel(Channel.UNLIMITED)
) : StreamObserver, ReceiveChannel by channel {

    override fun onNext(value: E) {
        channel.offer(value)
    }

    override fun onError(t: Throwable?) {
        channel.close(cause = t)
    }

    override fun onCompleted() {
        channel.close(cause = null)
    }
}

class ContextCoroutineContextElement : ThreadContextElement {

    companion object Key : CoroutineContext.Key

    private val grpcContext: Context = Context.current()

    override val key: CoroutineContext.Key
        get() = Key

    override fun updateThreadContext(context: CoroutineContext): Context =
        grpcContext.attach()

    override fun restoreThreadContext(context: CoroutineContext, oldState: Context) =
        grpcContext.detach(oldState)
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy