solution: mark Upstream status right after WS connect/disconnect
This commit is contained in:
@@ -61,7 +61,7 @@ abstract class DefaultUpstream(
|
||||
return status.get().status
|
||||
}
|
||||
|
||||
fun setStatus(avail: UpstreamAvailability) {
|
||||
open fun setStatus(avail: UpstreamAvailability) {
|
||||
status.updateAndGet { curr ->
|
||||
Status(curr.lag, avail, statusByLag(curr.lag, avail))
|
||||
}
|
||||
|
||||
@@ -74,7 +74,8 @@ open class EthereumRpcUpstream(
|
||||
|
||||
open fun createHead(): Head {
|
||||
return if (ethereumWsFactory != null) {
|
||||
val ws = ethereumWsFactory.create(null).apply {
|
||||
// do not set upstream to the WS, since it doesn't control the RPC upstream
|
||||
val ws = ethereumWsFactory.create(null, null, null).apply {
|
||||
connect()
|
||||
}
|
||||
val wsHead = EthereumWsHead(ws).apply {
|
||||
|
||||
@@ -32,7 +32,7 @@ import reactor.core.scheduler.Schedulers
|
||||
import java.time.Duration
|
||||
import java.util.concurrent.Executors
|
||||
|
||||
class EthereumUpstreamValidator(
|
||||
open class EthereumUpstreamValidator(
|
||||
private val upstream: EthereumUpstream,
|
||||
private val options: UpstreamsConfig.Options
|
||||
) {
|
||||
@@ -43,7 +43,7 @@ class EthereumUpstreamValidator(
|
||||
|
||||
private val objectMapper: ObjectMapper = Global.objectMapper
|
||||
|
||||
fun validate(): Mono<UpstreamAvailability> {
|
||||
open fun validate(): Mono<UpstreamAvailability> {
|
||||
return upstream
|
||||
.getApi()
|
||||
.read(JsonRpcRequest("eth_syncing", listOf()))
|
||||
|
||||
@@ -21,6 +21,8 @@ import io.emeraldpay.dshackle.Global
|
||||
import io.emeraldpay.dshackle.SilentException
|
||||
import io.emeraldpay.dshackle.config.AuthConfig
|
||||
import io.emeraldpay.dshackle.data.BlockContainer
|
||||
import io.emeraldpay.dshackle.upstream.DefaultUpstream
|
||||
import io.emeraldpay.dshackle.upstream.UpstreamAvailability
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.ResponseWSParser
|
||||
@@ -64,15 +66,17 @@ class EthereumWsFactory(
|
||||
|
||||
var basicAuth: AuthConfig.ClientBasicAuth? = null
|
||||
|
||||
fun create(rpcMetrics: RpcMetrics?): EthereumWs {
|
||||
return EthereumWs(uri, origin, basicAuth, rpcMetrics)
|
||||
fun create(upstream: DefaultUpstream?, validator: EthereumUpstreamValidator?, rpcMetrics: RpcMetrics?): EthereumWs {
|
||||
return EthereumWs(uri, origin, basicAuth, rpcMetrics, upstream, validator)
|
||||
}
|
||||
|
||||
class EthereumWs(
|
||||
private val uri: URI,
|
||||
private val origin: URI,
|
||||
private val basicAuth: AuthConfig.ClientBasicAuth?,
|
||||
private val rpcMetrics: RpcMetrics?
|
||||
private val rpcMetrics: RpcMetrics?,
|
||||
private val upstream: DefaultUpstream?,
|
||||
private val validator: EthereumUpstreamValidator?
|
||||
) : AutoCloseable {
|
||||
|
||||
companion object {
|
||||
@@ -154,6 +158,8 @@ class EthereumWsFactory(
|
||||
connection = HttpClient.create()
|
||||
.doOnDisconnected {
|
||||
log.info("Disconnected from $uri")
|
||||
// mark upstream as UNAVAIL
|
||||
upstream?.setStatus(UpstreamAvailability.UNAVAILABLE)
|
||||
if (keepConnection) {
|
||||
tryReconnectLater()
|
||||
}
|
||||
@@ -203,6 +209,9 @@ class EthereumWsFactory(
|
||||
//restart backoff after connection
|
||||
currentBackOff = reconnectBackoff.start()
|
||||
|
||||
//validate the connection, it can also be UNAVAIL if market as such after disconnect
|
||||
validator?.validate()
|
||||
|
||||
val consumer = inbound
|
||||
// Accept up to 15Mb messages, same config is used by Geth
|
||||
.aggregateFrames(15 * 1024 * 1024)
|
||||
|
||||
@@ -53,6 +53,7 @@ class EthereumWsUpstream(
|
||||
private val api: JsonRpcWsClient
|
||||
|
||||
private var validatorSubscription: Disposable? = null
|
||||
private val validator: EthereumUpstreamValidator
|
||||
|
||||
init {
|
||||
val metricsTags = listOf(
|
||||
@@ -72,7 +73,9 @@ class EthereumWsUpstream(
|
||||
.register(Metrics.globalRegistry)
|
||||
)
|
||||
|
||||
connection = ethereumWsFactory.create(metrics)
|
||||
validator = EthereumUpstreamValidator(this, getOptions())
|
||||
|
||||
connection = ethereumWsFactory.create(this, validator, metrics)
|
||||
head = EthereumWsHead(connection)
|
||||
api = JsonRpcWsClient(connection)
|
||||
}
|
||||
@@ -102,7 +105,6 @@ class EthereumWsUpstream(
|
||||
head.start()
|
||||
|
||||
log.debug("Start validation for upstream ${this.getId()}")
|
||||
val validator = EthereumUpstreamValidator(this, getOptions())
|
||||
validatorSubscription = validator.start()
|
||||
.subscribe(this::setStatus)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user