package actor.proto

import actor.proto.mailbox.SystemMessage
import kotlinx.coroutines.experimental.CompletableDeferred
import kotlinx.coroutines.experimental.withTimeout
import java.time.Duration
import java.util.concurrent.TimeUnit

class DeferredProcess<out T>(private val timeout: Duration = Duration.ofMillis(5000)) : Process() {
    val pid = ProcessRegistry.put(ProcessRegistry.nextId(), this)
    private val cd = CompletableDeferred<T>()
    override fun sendUserMessage(pid: PID, message: Any) {
        val m = when (message) {
            is MessageEnvelope -> message.message
            else -> message
        }
        @Suppress("UNCHECKED_CAST")
        cd.complete(m as T)
    }

    override fun sendSystemMessage(pid: PID, message: SystemMessage) {}

    suspend fun await(): T {
        val result = withTimeout(timeout.toMillis(), TimeUnit.MILLISECONDS) { cd.await() }
        ProcessRegistry.remove(pid)
        return result
    }
}
package actor.proto

import actor.proto.mailbox.SystemMessage
import kotlinx.coroutines.experimental.CompletableDeferred
import kotlinx.coroutines.experimental.withTimeout
import java.time.Duration
import java.util.concurrent.TimeUnit

class DeferredProcess<out T>(private val timeout: Duration = Duration.ofMillis(5000)) : Process() {
    val pid = ProcessRegistry.put(ProcessRegistry.nextId(), this)
    private val cd = CompletableDeferred<T>()
    override fun sendUserMessage(pid: PID, message: Any) {
        val m = when (message) {
            is MessageEnvelope -> message.message
            else -> message
        }
        @Suppress("UNCHECKED_CAST")
        cd.complete(m as T)
    }

    override fun sendSystemMessage(pid: PID, message: SystemMessage) {}

    suspend fun await(): T {
        try {
            val result = withTimeout(timeout.toMillis(), TimeUnit.MILLISECONDS) { cd.await() }
            ProcessRegistry.remove(pid)
            return result;
        } catch (exception: Exception) {
            ProcessRegistry.remove(pid)
            throw exception;
        }
    }
}
Remove from registry when an exception (including timeout) occurs
Remove from registry when an exception (including timeout) occurs

AsynkronIT/protoactor-kotlin,AsynkronIT/protoactor-kotlin,AsynkronIT/protoactor-kotlin