Check if config was reloaded, remove all upstream metrics if it was r… (#327)
This commit is contained in:
@@ -43,9 +43,11 @@ class ReloadConfigSetup(
|
||||
try {
|
||||
log.info("Reloading config...")
|
||||
|
||||
reloadConfig()
|
||||
|
||||
log.info("Config is reloaded")
|
||||
if (reloadConfig()) {
|
||||
log.info("Config is reloaded")
|
||||
} else {
|
||||
log.info("There is nothing to reload, config is the same")
|
||||
}
|
||||
} finally {
|
||||
reloadLock.unlock()
|
||||
}
|
||||
@@ -54,10 +56,14 @@ class ReloadConfigSetup(
|
||||
}
|
||||
}
|
||||
|
||||
private fun reloadConfig() {
|
||||
private fun reloadConfig(): Boolean {
|
||||
val newUpstreamsConfig = reloadConfigService.readUpstreamsConfig()
|
||||
val currentUpstreamsConfig = reloadConfigService.currentUpstreamsConfig()
|
||||
|
||||
if (newUpstreamsConfig == currentUpstreamsConfig) {
|
||||
return false
|
||||
}
|
||||
|
||||
val chainsToReload = analyzeDefaultOptions(
|
||||
currentUpstreamsConfig.defaultOptions,
|
||||
newUpstreamsConfig.defaultOptions,
|
||||
@@ -76,6 +82,8 @@ class ReloadConfigSetup(
|
||||
reloadConfigUpstreamService.reloadUpstreams(chainsToReload, upstreamsToRemove, upstreamsToAdd, newUpstreamsConfig)
|
||||
|
||||
reloadConfigService.updateUpstreamsConfig(newUpstreamsConfig)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
private fun analyzeUpstreams(
|
||||
|
||||
@@ -10,7 +10,7 @@ import org.springframework.context.ApplicationEventPublisher
|
||||
import org.springframework.stereotype.Component
|
||||
|
||||
@Component
|
||||
class ReloadConfigUpstreamService(
|
||||
open class ReloadConfigUpstreamService(
|
||||
private val eventPublisher: ApplicationEventPublisher,
|
||||
private val multistreamHolder: CurrentMultistreamHolder,
|
||||
private val configuredUpstreams: ConfiguredUpstreams,
|
||||
|
||||
@@ -4,3 +4,7 @@ import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcResponse
|
||||
|
||||
typealias JsonRpcReader = Reader<JsonRpcRequest, JsonRpcResponse>
|
||||
|
||||
interface JsonRpcHttpReader : JsonRpcReader {
|
||||
fun onStop()
|
||||
}
|
||||
|
||||
@@ -38,7 +38,6 @@ import io.emeraldpay.dshackle.config.UpstreamsConfig.HttpEndpoint
|
||||
import io.emeraldpay.dshackle.config.UpstreamsConfig.RpcConnection
|
||||
import io.emeraldpay.dshackle.foundation.ChainOptions
|
||||
import io.emeraldpay.dshackle.foundation.ChainOptions.Options
|
||||
import io.emeraldpay.dshackle.reader.JsonRpcReader
|
||||
import io.emeraldpay.dshackle.upstream.BlockValidator
|
||||
import io.emeraldpay.dshackle.upstream.CallTargetsHolder
|
||||
import io.emeraldpay.dshackle.upstream.Head
|
||||
@@ -343,7 +342,7 @@ open class ConfiguredUpstreams(
|
||||
log.warn("Upstream doesn't have API configuration")
|
||||
return null
|
||||
}
|
||||
val directApi: JsonRpcReader = httpFactory.create(config.id, chain)
|
||||
val directApi = httpFactory.create(config.id, chain)
|
||||
val esplora = conn.esplora?.let { endpoint ->
|
||||
val tls = endpoint.tls?.let { tls ->
|
||||
tls.ca?.let { ca ->
|
||||
|
||||
@@ -18,6 +18,7 @@ package io.emeraldpay.dshackle.upstream
|
||||
import io.emeraldpay.dshackle.data.BlockContainer
|
||||
import io.emeraldpay.dshackle.upstream.forkchoice.ForkChoice
|
||||
import io.micrometer.core.instrument.Gauge
|
||||
import io.micrometer.core.instrument.Meter
|
||||
import io.micrometer.core.instrument.Metrics
|
||||
import org.slf4j.LoggerFactory
|
||||
import reactor.core.Disposable
|
||||
@@ -32,7 +33,6 @@ import java.util.concurrent.Executors
|
||||
import java.util.concurrent.Future
|
||||
import java.util.concurrent.TimeUnit
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
import java.util.concurrent.locks.ReentrantLock
|
||||
|
||||
abstract class AbstractHead @JvmOverloads constructor(
|
||||
@@ -57,14 +57,24 @@ abstract class AbstractHead @JvmOverloads constructor(
|
||||
private var future: Future<*>? = null
|
||||
private val delayed = AtomicBoolean(false)
|
||||
|
||||
private val metrics = mutableSetOf<Meter>()
|
||||
|
||||
init {
|
||||
val className = this.javaClass.simpleName
|
||||
Gauge.builder("stuck_head", delayed) {
|
||||
if (it.get()) 1.0 else 0.0
|
||||
}.tag("upstream", upstreamId).tag("class", className).register(Metrics.globalRegistry)
|
||||
}
|
||||
.tag("upstream", upstreamId)
|
||||
.tag("class", className)
|
||||
.register(Metrics.globalRegistry)
|
||||
.also { metrics.add(it) }
|
||||
Gauge.builder("current_head", forkChoice) {
|
||||
it.getHead()?.height?.toDouble() ?: 0.0
|
||||
}.tag("upstream", upstreamId).tag("class", className).register(Metrics.globalRegistry)
|
||||
}
|
||||
.tag("upstream", upstreamId)
|
||||
.tag("class", className)
|
||||
.register(Metrics.globalRegistry)
|
||||
.also { metrics.add(it) }
|
||||
}
|
||||
|
||||
fun follow(source: Flux<BlockContainer>): Disposable {
|
||||
@@ -147,6 +157,7 @@ abstract class AbstractHead @JvmOverloads constructor(
|
||||
it.cancel(true)
|
||||
}
|
||||
future = null
|
||||
metrics.forEach { Metrics.globalRegistry.remove(it) }
|
||||
}
|
||||
|
||||
protected open fun onNoHeadUpdates() {
|
||||
@@ -176,10 +187,4 @@ abstract class AbstractHead @JvmOverloads constructor(
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun toHeadCountMetric(counter: AtomicInteger, status: String) {
|
||||
Gauge.builder("head_count", counter) {
|
||||
it.get().toDouble()
|
||||
}.tag("class", this.javaClass.simpleName).tag("status", status).register(Metrics.globalRegistry)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package io.emeraldpay.dshackle.upstream
|
||||
|
||||
import io.emeraldpay.dshackle.Chain
|
||||
import io.emeraldpay.dshackle.reader.JsonRpcReader
|
||||
import io.emeraldpay.dshackle.reader.JsonRpcHttpReader
|
||||
|
||||
interface HttpFactory {
|
||||
fun create(id: String?, chain: Chain): JsonRpcReader
|
||||
fun create(id: String?, chain: Chain): JsonRpcHttpReader
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ package io.emeraldpay.dshackle.upstream
|
||||
|
||||
import io.emeraldpay.dshackle.Chain
|
||||
import io.emeraldpay.dshackle.config.AuthConfig
|
||||
import io.emeraldpay.dshackle.reader.JsonRpcReader
|
||||
import io.emeraldpay.dshackle.reader.JsonRpcHttpReader
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcHttpClient
|
||||
import io.emeraldpay.dshackle.upstream.rpcclient.RpcMetrics
|
||||
import io.micrometer.core.instrument.Counter
|
||||
@@ -15,7 +15,7 @@ open class HttpRpcFactory(
|
||||
private val basicAuth: AuthConfig.ClientBasicAuth?,
|
||||
private val tls: ByteArray?,
|
||||
) : HttpFactory {
|
||||
override fun create(id: String?, chain: Chain): JsonRpcReader {
|
||||
override fun create(id: String?, chain: Chain): JsonRpcHttpReader {
|
||||
val metricsTags = listOf(
|
||||
// "unknown" is not supposed to happen
|
||||
Tag.of("upstream", id ?: "unknown"),
|
||||
|
||||
@@ -19,6 +19,7 @@ import io.emeraldpay.dshackle.Chain
|
||||
import io.emeraldpay.dshackle.config.ChainsConfig
|
||||
import io.emeraldpay.dshackle.config.UpstreamsConfig
|
||||
import io.emeraldpay.dshackle.foundation.ChainOptions
|
||||
import io.emeraldpay.dshackle.reader.JsonRpcHttpReader
|
||||
import io.emeraldpay.dshackle.reader.JsonRpcReader
|
||||
import io.emeraldpay.dshackle.startup.QuorumForLabels
|
||||
import io.emeraldpay.dshackle.upstream.Capability
|
||||
@@ -32,7 +33,7 @@ import reactor.core.Disposable
|
||||
open class BitcoinRpcUpstream(
|
||||
id: String,
|
||||
chain: Chain,
|
||||
private val directApi: JsonRpcReader,
|
||||
private val directApi: JsonRpcHttpReader,
|
||||
private val head: Head,
|
||||
options: ChainOptions.Options,
|
||||
role: UpstreamsConfig.UpstreamRole,
|
||||
@@ -115,5 +116,6 @@ open class BitcoinRpcUpstream(
|
||||
head.stop()
|
||||
}
|
||||
validatorSubscription?.dispose()
|
||||
directApi.onStop()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package io.emeraldpay.dshackle.upstream.generic.connectors
|
||||
|
||||
import io.emeraldpay.dshackle.cache.Caches
|
||||
import io.emeraldpay.dshackle.cache.CachesEnabled
|
||||
import io.emeraldpay.dshackle.reader.JsonRpcHttpReader
|
||||
import io.emeraldpay.dshackle.reader.JsonRpcReader
|
||||
import io.emeraldpay.dshackle.upstream.BlockValidator
|
||||
import io.emeraldpay.dshackle.upstream.DefaultUpstream
|
||||
@@ -31,7 +32,7 @@ import java.time.Duration
|
||||
|
||||
class GenericRpcConnector(
|
||||
connectorType: ConnectorMode,
|
||||
private val directReader: JsonRpcReader,
|
||||
private val directReader: JsonRpcHttpReader,
|
||||
wsFactory: WsConnectionPoolFactory?,
|
||||
upstream: DefaultUpstream,
|
||||
forkChoice: ForkChoice,
|
||||
@@ -137,6 +138,7 @@ class GenericRpcConnector(
|
||||
head.stop()
|
||||
}
|
||||
pool?.close()
|
||||
directReader.onStop()
|
||||
}
|
||||
|
||||
override fun getIngressReader(): JsonRpcReader {
|
||||
|
||||
@@ -16,9 +16,10 @@
|
||||
package io.emeraldpay.dshackle.upstream.rpcclient
|
||||
|
||||
import io.emeraldpay.dshackle.config.AuthConfig
|
||||
import io.emeraldpay.dshackle.reader.JsonRpcReader
|
||||
import io.emeraldpay.dshackle.reader.JsonRpcHttpReader
|
||||
import io.emeraldpay.etherjar.rpc.RpcException
|
||||
import io.emeraldpay.etherjar.rpc.RpcResponseError
|
||||
import io.micrometer.core.instrument.Metrics
|
||||
import io.netty.buffer.Unpooled
|
||||
import io.netty.handler.codec.http.HttpHeaderNames
|
||||
import io.netty.handler.codec.http.HttpHeaders
|
||||
@@ -47,7 +48,7 @@ class JsonRpcHttpClient(
|
||||
private val metrics: RpcMetrics,
|
||||
basicAuth: AuthConfig.ClientBasicAuth? = null,
|
||||
tlsCAAuth: ByteArray? = null,
|
||||
) : JsonRpcReader {
|
||||
) : JsonRpcHttpReader {
|
||||
|
||||
private val parser = ResponseRpcParser()
|
||||
private val httpClient: HttpClient
|
||||
@@ -104,6 +105,11 @@ class JsonRpcHttpClient(
|
||||
}.single()
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
Metrics.globalRegistry.remove(metrics.timer)
|
||||
Metrics.globalRegistry.remove(metrics.fails)
|
||||
}
|
||||
|
||||
override fun read(key: JsonRpcRequest): Mono<JsonRpcResponse> {
|
||||
val startTime = StopWatch()
|
||||
return Mono.just(key)
|
||||
|
||||
Reference in New Issue
Block a user