@@ -67,11 +67,6 @@ abstract class AbstractHead @JvmOverloads constructor(
|
||||
}
|
||||
|
||||
fun follow(source: Flux<BlockContainer>): Disposable {
|
||||
if (completed) {
|
||||
// if stream was already completed it cannot accept messages (with FAIL_TERMINATED), so needs to be recreated
|
||||
stream = Sinks.many().multicast().directBestEffort<BlockContainer>()
|
||||
completed = false
|
||||
}
|
||||
return source
|
||||
.filter {
|
||||
log.trace("Filtering block $upstreamId block $it")
|
||||
@@ -85,9 +80,7 @@ abstract class AbstractHead @JvmOverloads constructor(
|
||||
log.warn("Received signal $upstreamId $it unexpectedly - restart head")
|
||||
lastHeadUpdated = 0L
|
||||
} else {
|
||||
log.warn("Received signal $upstreamId $it - stop emit new head")
|
||||
completed = true
|
||||
stream.tryEmitComplete()
|
||||
log.warn("Received signal $upstreamId $it, continue emit heads")
|
||||
}
|
||||
}
|
||||
.subscribeOn(Schedulers.boundedElastic())
|
||||
@@ -155,6 +148,9 @@ abstract class AbstractHead @JvmOverloads constructor(
|
||||
future = null
|
||||
}
|
||||
|
||||
override fun onNoHeadUpdates() {
|
||||
}
|
||||
|
||||
override fun start() {
|
||||
stopping = false
|
||||
log.debug("Start ${this.javaClass.simpleName} $upstreamId")
|
||||
@@ -165,6 +161,7 @@ abstract class AbstractHead @JvmOverloads constructor(
|
||||
delayed.set(delay > awaitHeadTimeoutMs)
|
||||
if (delayed.get()) {
|
||||
log.warn("No head updates $upstreamId for $delay ms @ ${this.javaClass.simpleName}")
|
||||
onNoHeadUpdates()
|
||||
}
|
||||
}, 180, 30, TimeUnit.SECONDS
|
||||
)
|
||||
|
||||
@@ -36,4 +36,7 @@ class EmptyHead : Head {
|
||||
|
||||
override fun stop() {
|
||||
}
|
||||
|
||||
override fun onNoHeadUpdates() {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,4 +41,6 @@ interface Head {
|
||||
fun start()
|
||||
|
||||
fun stop()
|
||||
|
||||
fun onNoHeadUpdates()
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
|
||||
import io.emeraldpay.etherjar.rpc.json.BlockJson
|
||||
import io.emeraldpay.etherjar.rpc.json.TransactionRefJson
|
||||
import org.slf4j.LoggerFactory
|
||||
import reactor.core.Disposable
|
||||
import reactor.core.publisher.Flux
|
||||
import reactor.core.publisher.Mono
|
||||
@@ -44,6 +45,10 @@ class EthereumWsHead(
|
||||
private val skipEnhance: Boolean
|
||||
) : DefaultEthereumHead(upstreamId, forkChoice, blockValidator), Lifecycle {
|
||||
|
||||
companion object {
|
||||
private val log = LoggerFactory.getLogger(EthereumWsHead::class.java)
|
||||
}
|
||||
|
||||
private var subscription: Disposable? = null
|
||||
|
||||
override fun isRunning(): Boolean {
|
||||
@@ -61,6 +66,11 @@ class EthereumWsHead(
|
||||
this.subscription = super.follow(heads)
|
||||
}
|
||||
|
||||
override fun onNoHeadUpdates() {
|
||||
log.warn("Restart ws head, upstreamId: $upstreamId")
|
||||
start()
|
||||
}
|
||||
|
||||
fun listenNewHeads(): Flux<BlockContainer> {
|
||||
return wsSubscriptions.subscribe("newHeads")
|
||||
.map {
|
||||
|
||||
Reference in New Issue
Block a user