subscription heartbeat (#715)
This commit is contained in:
Submodule emerald-grpc updated: 9ae95ae1b5...9a2bedc999
@@ -32,5 +32,6 @@ class Defaults {
|
|||||||
val grpcServerPermitKeepAliveTime: Long = 15
|
val grpcServerPermitKeepAliveTime: Long = 15
|
||||||
val grpcServerMaxConnectionIdle: Long = 3600
|
val grpcServerMaxConnectionIdle: Long = 3600
|
||||||
val multistreamUnavailableMethodDisableDuration: Long = 20 // minutes
|
val multistreamUnavailableMethodDisableDuration: Long = 20 // minutes
|
||||||
|
val nativeSubscribeHeartbeatInterval: Duration = Duration.ofSeconds(30)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import com.google.protobuf.ByteString
|
|||||||
import io.emeraldpay.api.proto.BlockchainOuterClass
|
import io.emeraldpay.api.proto.BlockchainOuterClass
|
||||||
import io.emeraldpay.api.proto.BlockchainOuterClass.NativeSubscribeReplyItem
|
import io.emeraldpay.api.proto.BlockchainOuterClass.NativeSubscribeReplyItem
|
||||||
import io.emeraldpay.dshackle.Chain
|
import io.emeraldpay.dshackle.Chain
|
||||||
|
import io.emeraldpay.dshackle.Defaults
|
||||||
import io.emeraldpay.dshackle.Global
|
import io.emeraldpay.dshackle.Global
|
||||||
import io.emeraldpay.dshackle.SilentException
|
import io.emeraldpay.dshackle.SilentException
|
||||||
import io.emeraldpay.dshackle.upstream.Multistream
|
import io.emeraldpay.dshackle.upstream.Multistream
|
||||||
@@ -34,6 +35,7 @@ import org.springframework.beans.factory.annotation.Autowired
|
|||||||
import org.springframework.stereotype.Service
|
import org.springframework.stereotype.Service
|
||||||
import reactor.core.publisher.Flux
|
import reactor.core.publisher.Flux
|
||||||
import reactor.core.publisher.Mono
|
import reactor.core.publisher.Mono
|
||||||
|
import java.util.concurrent.atomic.AtomicLong
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
open class NativeSubscribe(
|
open class NativeSubscribe(
|
||||||
@@ -51,14 +53,26 @@ open class NativeSubscribe(
|
|||||||
.flatMapMany {
|
.flatMapMany {
|
||||||
it ->
|
it ->
|
||||||
val subscriptionId = it.subscriptionId
|
val subscriptionId = it.subscriptionId
|
||||||
Mono.just(it)
|
val dataStream = Mono.just(it)
|
||||||
.flatMapMany {
|
.flatMapMany {
|
||||||
start(it, subscriptionId)
|
start(it, subscriptionId)
|
||||||
}
|
}
|
||||||
.map(this@NativeSubscribe::convertToProto)
|
.map(this@NativeSubscribe::convertToProto)
|
||||||
|
|
||||||
|
val lastMessageTime = AtomicLong(System.currentTimeMillis())
|
||||||
|
|
||||||
|
val heartbeatStream = Flux.interval(Defaults.nativeSubscribeHeartbeatInterval)
|
||||||
|
.filter { System.currentTimeMillis() - lastMessageTime.get() >= Defaults.nativeSubscribeHeartbeatInterval.toMillis() }
|
||||||
|
.map { createHeartbeat() }
|
||||||
|
|
||||||
|
Flux.merge(
|
||||||
|
dataStream.doOnNext { lastMessageTime.set(System.currentTimeMillis()) },
|
||||||
|
heartbeatStream,
|
||||||
|
)
|
||||||
.doOnCancel {
|
.doOnCancel {
|
||||||
log.warn("Subscription $subscriptionId cancelled")
|
log.warn("Subscription $subscriptionId cancelled")
|
||||||
}.onErrorMap {
|
}
|
||||||
|
.onErrorMap {
|
||||||
convertToStatus(it, subscriptionId)
|
convertToStatus(it, subscriptionId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -172,6 +186,12 @@ open class NativeSubscribe(
|
|||||||
return msg.build()
|
return msg.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun createHeartbeat(): NativeSubscribeReplyItem {
|
||||||
|
return NativeSubscribeReplyItem.newBuilder()
|
||||||
|
.setHeartbeat(true)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
data class ResponseHolder(
|
data class ResponseHolder(
|
||||||
val response: Any,
|
val response: Any,
|
||||||
val nonce: Long?,
|
val nonce: Long?,
|
||||||
|
|||||||
Reference in New Issue
Block a user