use head scheduler instead of stock schedulers in other parts of system

This commit is contained in:
a10zn8
2023-04-21 18:02:25 +08:00
parent f218e6e73b
commit b97108fd35
17 changed files with 63 additions and 60 deletions

View File

@@ -388,6 +388,7 @@ open class ConfiguredUpstreams(
id, chain, id, chain,
endpoint.url, endpoint.url,
endpoint.origin ?: URI("http://localhost"), endpoint.origin ?: URI("http://localhost"),
headScheduler
).apply { ).apply {
config = endpoint config = endpoint
basicAuth = endpoint.basicAuth basicAuth = endpoint.basicAuth

View File

@@ -10,9 +10,11 @@ import io.emeraldpay.etherjar.domain.Address
import io.emeraldpay.etherjar.hex.Hex32 import io.emeraldpay.etherjar.hex.Hex32
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import reactor.core.publisher.Flux import reactor.core.publisher.Flux
import reactor.core.scheduler.Scheduler
open class EthereumEgressSubscription( open class EthereumEgressSubscription(
val upstream: EthereumLikeMultistream, val upstream: EthereumLikeMultistream,
val scheduler: Scheduler,
val pendingTxesSource: PendingTxesSource? val pendingTxesSource: PendingTxesSource?
) : EgressSubscription { ) : EgressSubscription {
@@ -37,8 +39,8 @@ open class EthereumEgressSubscription(
} }
} }
private val newHeads = ConnectNewHeads(upstream) private val newHeads = ConnectNewHeads(upstream, scheduler)
open val logs = ConnectLogs(upstream) open val logs = ConnectLogs(upstream, scheduler)
private val syncing = ConnectSyncing(upstream) private val syncing = ConnectSyncing(upstream)
override fun getAvailableTopics() = availableTopics override fun getAvailableTopics() = availableTopics

View File

@@ -63,7 +63,7 @@ open class EthereumMultistream(
ConcurrentReferenceHashMap(16, ConcurrentReferenceHashMap.ReferenceType.WEAK) ConcurrentReferenceHashMap(16, ConcurrentReferenceHashMap.ReferenceType.WEAK)
private val reader: EthereumCachingReader = EthereumCachingReader(this, this.caches, getMethodsFactory(), tracer) private val reader: EthereumCachingReader = EthereumCachingReader(this, this.caches, getMethodsFactory(), tracer)
private var subscribe = EthereumEgressSubscription(this, NoPendingTxes()) private var subscribe = EthereumEgressSubscription(this, headScheduler, NoPendingTxes())
private val supportsEIP1559 = when (chain) { private val supportsEIP1559 = when (chain) {
Chain.ETHEREUM, Chain.TESTNET_ROPSTEN, Chain.ETHEREUM, Chain.TESTNET_ROPSTEN,
@@ -102,7 +102,7 @@ open class EthereumMultistream(
AggregatedPendingTxes(it) AggregatedPendingTxes(it)
} }
} }
subscribe = EthereumEgressSubscription(this, pendingTxes) subscribe = EthereumEgressSubscription(this, headScheduler, pendingTxes)
} }
override fun start() { override fun start() {

View File

@@ -8,6 +8,7 @@ import io.micrometer.core.instrument.Counter
import io.micrometer.core.instrument.Metrics import io.micrometer.core.instrument.Metrics
import io.micrometer.core.instrument.Tag import io.micrometer.core.instrument.Tag
import io.micrometer.core.instrument.Timer import io.micrometer.core.instrument.Timer
import reactor.core.scheduler.Scheduler
import java.net.URI import java.net.URI
open class EthereumWsConnectionFactory( open class EthereumWsConnectionFactory(
@@ -15,6 +16,7 @@ open class EthereumWsConnectionFactory(
private val chain: Chain, private val chain: Chain,
private val uri: URI, private val uri: URI,
private val origin: URI, private val origin: URI,
private val scheduler: Scheduler
) { ) {
var basicAuth: AuthConfig.ClientBasicAuth? = null var basicAuth: AuthConfig.ClientBasicAuth? = null
@@ -42,7 +44,7 @@ open class EthereumWsConnectionFactory(
} }
open fun createWsConnection(connIndex: Int = 0, onDisconnect: () -> Unit): WsConnection = open fun createWsConnection(connIndex: Int = 0, onDisconnect: () -> Unit): WsConnection =
WsConnectionImpl(uri, origin, basicAuth, metrics(connIndex), onDisconnect).also { ws -> WsConnectionImpl(uri, origin, basicAuth, metrics(connIndex), onDisconnect, scheduler).also { ws ->
config?.frameSize?.let { config?.frameSize?.let {
ws.frameSize = it ws.frameSize = it
} }

View File

@@ -33,7 +33,6 @@ import reactor.core.publisher.Flux
import reactor.core.publisher.Mono import reactor.core.publisher.Mono
import reactor.core.publisher.Sinks import reactor.core.publisher.Sinks
import reactor.core.scheduler.Scheduler import reactor.core.scheduler.Scheduler
import reactor.core.scheduler.Schedulers
import reactor.retry.Repeat import reactor.retry.Repeat
import java.time.Duration import java.time.Duration
@@ -45,7 +44,7 @@ class EthereumWsHead(
private val wsSubscriptions: WsSubscriptions, private val wsSubscriptions: WsSubscriptions,
private val skipEnhance: Boolean, private val skipEnhance: Boolean,
private val wsConnectionResubscribeScheduler: Scheduler, private val wsConnectionResubscribeScheduler: Scheduler,
headScheduler: Scheduler, private val headScheduler: Scheduler,
) : DefaultEthereumHead(upstreamId, forkChoice, blockValidator, headScheduler), Lifecycle { ) : DefaultEthereumHead(upstreamId, forkChoice, blockValidator, headScheduler), Lifecycle {
private var connectionId: String? = null private var connectionId: String? = null
@@ -119,7 +118,7 @@ class EthereumWsHead(
} }
.flatMap(JsonRpcResponse::requireResult) .flatMap(JsonRpcResponse::requireResult)
.map { BlockContainer.fromEthereumJson(it, upstreamId) } .map { BlockContainer.fromEthereumJson(it, upstreamId) }
.subscribeOn(Schedulers.boundedElastic()) .subscribeOn(headScheduler)
.timeout(Defaults.timeoutInternal, Mono.empty()) .timeout(Defaults.timeoutInternal, Mono.empty())
}.repeatWhenEmpty { n -> }.repeatWhenEmpty { n ->
Repeat.times<Any>(5) Repeat.times<Any>(5)

View File

@@ -44,7 +44,7 @@ import reactor.core.Disposable
import reactor.core.publisher.Flux import reactor.core.publisher.Flux
import reactor.core.publisher.Mono import reactor.core.publisher.Mono
import reactor.core.publisher.Sinks import reactor.core.publisher.Sinks
import reactor.core.scheduler.Schedulers import reactor.core.scheduler.Scheduler
import reactor.netty.http.client.HttpClient import reactor.netty.http.client.HttpClient
import reactor.netty.http.client.WebsocketClientSpec import reactor.netty.http.client.WebsocketClientSpec
import reactor.netty.http.websocket.WebsocketInbound import reactor.netty.http.websocket.WebsocketInbound
@@ -67,7 +67,8 @@ open class WsConnectionImpl(
private val origin: URI, private val origin: URI,
private val basicAuth: AuthConfig.ClientBasicAuth?, private val basicAuth: AuthConfig.ClientBasicAuth?,
private val rpcMetrics: RpcMetrics?, private val rpcMetrics: RpcMetrics?,
private val onDisconnect: () -> Unit private val onDisconnect: () -> Unit,
private val scheduler: Scheduler
) : AutoCloseable, WsConnection, Cloneable { ) : AutoCloseable, WsConnection, Cloneable {
companion object { companion object {
@@ -292,8 +293,8 @@ open class WsConnectionImpl(
return outbound.send( return outbound.send(
Flux.merge( Flux.merge(
calls.subscribeOn(Schedulers.boundedElastic()), calls.subscribeOn(scheduler),
consumer.then(Mono.empty<ByteBuf>()).subscribeOn(Schedulers.boundedElastic()) consumer.then(Mono.empty<ByteBuf>()).subscribeOn(scheduler)
) )
) )
} }

View File

@@ -22,9 +22,8 @@ import io.emeraldpay.dshackle.upstream.Head
import io.emeraldpay.dshackle.upstream.Selector import io.emeraldpay.dshackle.upstream.Selector
import io.emeraldpay.dshackle.upstream.SubscriptionConnect import io.emeraldpay.dshackle.upstream.SubscriptionConnect
import io.emeraldpay.dshackle.upstream.ethereum.EthereumLikeMultistream import io.emeraldpay.dshackle.upstream.ethereum.EthereumLikeMultistream
import org.slf4j.LoggerFactory
import reactor.core.publisher.Flux import reactor.core.publisher.Flux
import reactor.core.scheduler.Schedulers import reactor.core.scheduler.Scheduler
import java.time.Duration import java.time.Duration
import java.util.LinkedList import java.util.LinkedList
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
@@ -33,11 +32,11 @@ import kotlin.concurrent.read
import kotlin.concurrent.write import kotlin.concurrent.write
class ConnectBlockUpdates( class ConnectBlockUpdates(
private val upstream: EthereumLikeMultistream private val upstream: EthereumLikeMultistream,
private val scheduler: Scheduler
) : SubscriptionConnect<ConnectBlockUpdates.Update> { ) : SubscriptionConnect<ConnectBlockUpdates.Update> {
companion object { companion object {
private val log = LoggerFactory.getLogger(ConnectBlockUpdates::class.java)
private const val HISTORY_LIMIT = 6 * 3 private const val HISTORY_LIMIT = 6 * 3
} }
@@ -53,7 +52,7 @@ class ConnectBlockUpdates(
override fun connect(matcher: Selector.Matcher): Flux<Update> { override fun connect(matcher: Selector.Matcher): Flux<Update> {
return connected.computeIfAbsent(matcher.describeInternal()) { key -> return connected.computeIfAbsent(matcher.describeInternal()) { key ->
extract(upstream.getHead(matcher)) extract(upstream.getHead(matcher))
.publishOn(Schedulers.boundedElastic()) .publishOn(scheduler)
.publish() .publish()
.refCount(1, Duration.ofSeconds(60)) .refCount(1, Duration.ofSeconds(60))
.doFinally { .doFinally {

View File

@@ -22,8 +22,8 @@ import io.emeraldpay.dshackle.upstream.ethereum.subscribe.json.LogMessage
import io.emeraldpay.etherjar.domain.Address import io.emeraldpay.etherjar.domain.Address
import io.emeraldpay.etherjar.hex.Hex32 import io.emeraldpay.etherjar.hex.Hex32
import io.emeraldpay.etherjar.hex.HexDataComparator import io.emeraldpay.etherjar.hex.HexDataComparator
import org.slf4j.LoggerFactory
import reactor.core.publisher.Flux import reactor.core.publisher.Flux
import reactor.core.scheduler.Scheduler
import java.util.function.Function import java.util.function.Function
open class ConnectLogs( open class ConnectLogs(
@@ -32,14 +32,11 @@ open class ConnectLogs(
) { ) {
companion object { companion object {
private val log = LoggerFactory.getLogger(ConnectLogs::class.java)
private val ADDR_COMPARATOR = HexDataComparator() private val ADDR_COMPARATOR = HexDataComparator()
private val TOPIC_COMPARATOR = HexDataComparator() private val TOPIC_COMPARATOR = HexDataComparator()
} }
constructor(upstream: EthereumLikeMultistream) : this(upstream, ConnectBlockUpdates(upstream)) constructor(upstream: EthereumLikeMultistream, scheduler: Scheduler) : this(upstream, ConnectBlockUpdates(upstream, scheduler))
private val produceLogs = ProduceLogs(upstream) private val produceLogs = ProduceLogs(upstream)
fun start(matcher: Selector.Matcher): Flux<LogMessage> { fun start(matcher: Selector.Matcher): Flux<LogMessage> {

View File

@@ -19,9 +19,8 @@ import io.emeraldpay.dshackle.upstream.Selector
import io.emeraldpay.dshackle.upstream.SubscriptionConnect import io.emeraldpay.dshackle.upstream.SubscriptionConnect
import io.emeraldpay.dshackle.upstream.ethereum.EthereumLikeMultistream import io.emeraldpay.dshackle.upstream.ethereum.EthereumLikeMultistream
import io.emeraldpay.dshackle.upstream.ethereum.subscribe.json.NewHeadMessage import io.emeraldpay.dshackle.upstream.ethereum.subscribe.json.NewHeadMessage
import org.slf4j.LoggerFactory
import reactor.core.publisher.Flux import reactor.core.publisher.Flux
import reactor.core.scheduler.Schedulers import reactor.core.scheduler.Scheduler
import java.time.Duration import java.time.Duration
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
@@ -29,20 +28,17 @@ import java.util.concurrent.ConcurrentHashMap
* Connects/reconnects to the upstream to produce NewHeads messages * Connects/reconnects to the upstream to produce NewHeads messages
*/ */
class ConnectNewHeads( class ConnectNewHeads(
private val upstream: EthereumLikeMultistream private val upstream: EthereumLikeMultistream,
private val scheduler: Scheduler
) : SubscriptionConnect<NewHeadMessage> { ) : SubscriptionConnect<NewHeadMessage> {
companion object {
private val log = LoggerFactory.getLogger(ConnectNewHeads::class.java)
}
private val connected: MutableMap<String, Flux<NewHeadMessage>> = ConcurrentHashMap() private val connected: MutableMap<String, Flux<NewHeadMessage>> = ConcurrentHashMap()
override fun connect(matcher: Selector.Matcher): Flux<NewHeadMessage> = override fun connect(matcher: Selector.Matcher): Flux<NewHeadMessage> =
connected.computeIfAbsent(matcher.describeInternal()) { key -> connected.computeIfAbsent(matcher.describeInternal()) { key ->
ProduceNewHeads(upstream.getHead(matcher)) ProduceNewHeads(upstream.getHead(matcher))
.start() .start()
.publishOn(Schedulers.boundedElastic()) .publishOn(scheduler)
.publish() .publish()
.refCount(1, Duration.ofSeconds(60)) .refCount(1, Duration.ofSeconds(60))
.doFinally { .doFinally {

View File

@@ -19,7 +19,6 @@ import io.emeraldpay.dshackle.upstream.Selector
import io.emeraldpay.dshackle.upstream.SubscriptionConnect import io.emeraldpay.dshackle.upstream.SubscriptionConnect
import io.emeraldpay.dshackle.upstream.UpstreamAvailability import io.emeraldpay.dshackle.upstream.UpstreamAvailability
import io.emeraldpay.dshackle.upstream.ethereum.EthereumLikeMultistream import io.emeraldpay.dshackle.upstream.ethereum.EthereumLikeMultistream
import org.slf4j.LoggerFactory
import reactor.core.publisher.Flux import reactor.core.publisher.Flux
import java.time.Duration import java.time.Duration
import java.util.concurrent.locks.ReentrantLock import java.util.concurrent.locks.ReentrantLock
@@ -29,10 +28,6 @@ class ConnectSyncing(
private val upstream: EthereumLikeMultistream private val upstream: EthereumLikeMultistream
) : SubscriptionConnect<Boolean> { ) : SubscriptionConnect<Boolean> {
companion object {
private val log = LoggerFactory.getLogger(ConnectSyncing::class.java)
}
private var connected: Flux<Boolean>? = null private var connected: Flux<Boolean>? = null
private val connectLock = ReentrantLock() private val connectLock = ReentrantLock()

View File

@@ -58,7 +58,7 @@ open class EthereumPosMultiStream(
) )
private val reader: EthereumCachingReader = EthereumCachingReader(this, this.caches, getMethodsFactory(), tracer) private val reader: EthereumCachingReader = EthereumCachingReader(this, this.caches, getMethodsFactory(), tracer)
private var subscribe = EthereumEgressSubscription(this, NoPendingTxes()) private var subscribe = EthereumEgressSubscription(this, headScheduler, NoPendingTxes())
private val feeEstimation = EthereumPriorityFees(this, reader, 256) private val feeEstimation = EthereumPriorityFees(this, reader, 256)
private val filteredHeads: MutableMap<String, Head> = private val filteredHeads: MutableMap<String, Head> =
ConcurrentReferenceHashMap(16, ConcurrentReferenceHashMap.ReferenceType.WEAK) ConcurrentReferenceHashMap(16, ConcurrentReferenceHashMap.ReferenceType.WEAK)
@@ -198,6 +198,6 @@ open class EthereumPosMultiStream(
AggregatedPendingTxes(it) AggregatedPendingTxes(it)
} }
} }
subscribe = EthereumEgressSubscription(this, pendingTxes) subscribe = EthereumEgressSubscription(this, headScheduler, pendingTxes)
} }
} }

View File

@@ -19,13 +19,14 @@ import io.emeraldpay.dshackle.test.TestingCommons
import io.emeraldpay.dshackle.upstream.ethereum.subscribe.PendingTxesSource import io.emeraldpay.dshackle.upstream.ethereum.subscribe.PendingTxesSource
import io.emeraldpay.etherjar.domain.Address import io.emeraldpay.etherjar.domain.Address
import io.emeraldpay.etherjar.hex.Hex32 import io.emeraldpay.etherjar.hex.Hex32
import reactor.core.scheduler.Schedulers
import spock.lang.Specification import spock.lang.Specification
class EthereumEgressSubscriptionSpec extends Specification { class EthereumEgressSubscriptionSpec extends Specification {
def "read empty logs request"() { def "read empty logs request"() {
setup: setup:
def ethereumSubscribe = new EthereumEgressSubscription(TestingCommons.emptyMultistream() as EthereumPosMultiStream, Stub(PendingTxesSource)) def ethereumSubscribe = new EthereumEgressSubscription(TestingCommons.emptyMultistream() as EthereumPosMultiStream, Schedulers.boundedElastic(), Stub(PendingTxesSource))
when: when:
def act = ethereumSubscribe.readLogsRequest([:]) def act = ethereumSubscribe.readLogsRequest([:])
@@ -36,7 +37,7 @@ class EthereumEgressSubscriptionSpec extends Specification {
def "read single address logs request"() { def "read single address logs request"() {
setup: setup:
def ethereumSubscribe = new EthereumEgressSubscription(TestingCommons.emptyMultistream() as EthereumPosMultiStream, Stub(PendingTxesSource)) def ethereumSubscribe = new EthereumEgressSubscription(TestingCommons.emptyMultistream() as EthereumPosMultiStream, Schedulers.boundedElastic(), Stub(PendingTxesSource))
when: when:
def act = ethereumSubscribe.readLogsRequest([ def act = ethereumSubscribe.readLogsRequest([
address: "0x829bd824b016326a401d083b33d092293333a830" address: "0x829bd824b016326a401d083b33d092293333a830"
@@ -61,7 +62,7 @@ class EthereumEgressSubscriptionSpec extends Specification {
def "ignores invalid address for logs request"() { def "ignores invalid address for logs request"() {
setup: setup:
def ethereumSubscribe = new EthereumEgressSubscription(TestingCommons.emptyMultistream() as EthereumPosMultiStream, Stub(PendingTxesSource)) def ethereumSubscribe = new EthereumEgressSubscription(TestingCommons.emptyMultistream() as EthereumPosMultiStream, Schedulers.boundedElastic(), Stub(PendingTxesSource))
when: when:
def act = ethereumSubscribe.readLogsRequest([ def act = ethereumSubscribe.readLogsRequest([
address: "829bd824b016326a401d083b33d092293333a830" address: "829bd824b016326a401d083b33d092293333a830"
@@ -74,7 +75,7 @@ class EthereumEgressSubscriptionSpec extends Specification {
def "read multi address logs request"() { def "read multi address logs request"() {
setup: setup:
def ethereumSubscribe = new EthereumEgressSubscription(TestingCommons.emptyMultistream() as EthereumPosMultiStream, Stub(PendingTxesSource)) def ethereumSubscribe = new EthereumEgressSubscription(TestingCommons.emptyMultistream() as EthereumPosMultiStream, Schedulers.boundedElastic(), Stub(PendingTxesSource))
when: when:
def act = ethereumSubscribe.readLogsRequest([ def act = ethereumSubscribe.readLogsRequest([
address: ["0x829bd824b016326a401d083b33d092293333a830", "0x401d083b33d092293333a83829bd824b016326a0"] address: ["0x829bd824b016326a401d083b33d092293333a830", "0x401d083b33d092293333a83829bd824b016326a0"]
@@ -90,7 +91,7 @@ class EthereumEgressSubscriptionSpec extends Specification {
def "read single topic logs request"() { def "read single topic logs request"() {
setup: setup:
def ethereumSubscribe = new EthereumEgressSubscription(TestingCommons.emptyMultistream() as EthereumPosMultiStream, Stub(PendingTxesSource)) def ethereumSubscribe = new EthereumEgressSubscription(TestingCommons.emptyMultistream() as EthereumPosMultiStream, Schedulers.boundedElastic(), Stub(PendingTxesSource))
when: when:
def act = ethereumSubscribe.readLogsRequest([ def act = ethereumSubscribe.readLogsRequest([
topics: "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef" topics: "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"
@@ -115,7 +116,7 @@ class EthereumEgressSubscriptionSpec extends Specification {
def "read invalid topic for request"() { def "read invalid topic for request"() {
setup: setup:
def ethereumSubscribe = new EthereumEgressSubscription(TestingCommons.emptyMultistream() as EthereumPosMultiStream, Stub(PendingTxesSource)) def ethereumSubscribe = new EthereumEgressSubscription(TestingCommons.emptyMultistream() as EthereumPosMultiStream, Schedulers.boundedElastic(), Stub(PendingTxesSource))
when: when:
def act = ethereumSubscribe.readLogsRequest([ def act = ethereumSubscribe.readLogsRequest([
topics: [ topics: [
@@ -133,7 +134,7 @@ class EthereumEgressSubscriptionSpec extends Specification {
def "read multi topic logs request"() { def "read multi topic logs request"() {
setup: setup:
def ethereumSubscribe = new EthereumEgressSubscription(TestingCommons.emptyMultistream() as EthereumPosMultiStream, Stub(PendingTxesSource)) def ethereumSubscribe = new EthereumEgressSubscription(TestingCommons.emptyMultistream() as EthereumPosMultiStream, Schedulers.boundedElastic(), Stub(PendingTxesSource))
when: when:
def act = ethereumSubscribe.readLogsRequest([ def act = ethereumSubscribe.readLogsRequest([
topics: [ topics: [
@@ -152,7 +153,7 @@ class EthereumEgressSubscriptionSpec extends Specification {
def "read full logs request"() { def "read full logs request"() {
setup: setup:
def ethereumSubscribe = new EthereumEgressSubscription(TestingCommons.emptyMultistream() as EthereumPosMultiStream, Stub(PendingTxesSource)) def ethereumSubscribe = new EthereumEgressSubscription(TestingCommons.emptyMultistream() as EthereumPosMultiStream, Schedulers.boundedElastic(), Stub(PendingTxesSource))
when: when:
def act = ethereumSubscribe.readLogsRequest([ def act = ethereumSubscribe.readLogsRequest([
address: "0x298d492e8c1d909d3f63bc4a36c66c64acb3d695", address: "0x298d492e8c1d909d3f63bc4a36c66c64acb3d695",

View File

@@ -5,6 +5,7 @@ import io.emeraldpay.dshackle.test.MockWSServer
import io.emeraldpay.dshackle.upstream.DefaultUpstream import io.emeraldpay.dshackle.upstream.DefaultUpstream
import io.emeraldpay.dshackle.upstream.UpstreamAvailability import io.emeraldpay.dshackle.upstream.UpstreamAvailability
import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest import io.emeraldpay.dshackle.upstream.rpcclient.JsonRpcRequest
import reactor.core.scheduler.Schedulers
import reactor.test.StepVerifier import reactor.test.StepVerifier
import spock.lang.Shared import spock.lang.Shared
import spock.lang.Specification import spock.lang.Specification
@@ -38,7 +39,8 @@ class WsConnectionImplRealSpec extends Specification {
"test", "test",
Chain.ETHEREUM, Chain.ETHEREUM,
"ws://localhost:${port}".toURI(), "ws://localhost:${port}".toURI(),
"http://localhost:${port}".toURI() "http://localhost:${port}".toURI(),
Schedulers.parallel()
) )
).create(null).getConnection() ).create(null).getConnection()
} }
@@ -117,7 +119,8 @@ class WsConnectionImplRealSpec extends Specification {
"test", "test",
Chain.ETHEREUM, Chain.ETHEREUM,
"ws://localhost:${port}".toURI(), "ws://localhost:${port}".toURI(),
"http://localhost:${port}".toURI() "http://localhost:${port}".toURI(),
Schedulers.parallel()
) )
).create(up).getConnection() ).create(up).getConnection()
when: when:

View File

@@ -23,6 +23,7 @@ import io.emeraldpay.etherjar.domain.TransactionId
import io.emeraldpay.etherjar.rpc.RpcResponseError import io.emeraldpay.etherjar.rpc.RpcResponseError
import io.emeraldpay.etherjar.rpc.json.TransactionJson import io.emeraldpay.etherjar.rpc.json.TransactionJson
import reactor.core.publisher.Flux import reactor.core.publisher.Flux
import reactor.core.scheduler.Schedulers
import reactor.test.StepVerifier import reactor.test.StepVerifier
import spock.lang.Specification import spock.lang.Specification
@@ -39,7 +40,8 @@ class WsConnectionImplSpec extends Specification {
"test", "test",
Chain.ETHEREUM, Chain.ETHEREUM,
new URI("http://localhost"), new URI("http://localhost"),
new URI("http://localhost") new URI("http://localhost"),
Schedulers.parallel()
) )
) )
def apiMock = TestingCommons.api() def apiMock = TestingCommons.api()
@@ -73,7 +75,8 @@ class WsConnectionImplSpec extends Specification {
"test", "test",
Chain.ETHEREUM, Chain.ETHEREUM,
new URI("http://localhost"), new URI("http://localhost"),
new URI("http://localhost") new URI("http://localhost"),
Schedulers.parallel()
) )
) )
def apiMock = TestingCommons.api() def apiMock = TestingCommons.api()
@@ -105,7 +108,8 @@ class WsConnectionImplSpec extends Specification {
"test", "test",
Chain.ETHEREUM, Chain.ETHEREUM,
new URI("http://localhost"), new URI("http://localhost"),
new URI("http://localhost") new URI("http://localhost"),
Schedulers.parallel()
) )
) )
def apiMock = TestingCommons.api() def apiMock = TestingCommons.api()

View File

@@ -26,6 +26,7 @@ import io.emeraldpay.etherjar.domain.TransactionId
import io.emeraldpay.etherjar.rpc.json.BlockJson import io.emeraldpay.etherjar.rpc.json.BlockJson
import io.emeraldpay.etherjar.rpc.json.TransactionRefJson import io.emeraldpay.etherjar.rpc.json.TransactionRefJson
import reactor.core.publisher.Flux import reactor.core.publisher.Flux
import reactor.core.scheduler.Schedulers
import spock.lang.Specification import spock.lang.Specification
import java.time.Duration import java.time.Duration
@@ -37,7 +38,7 @@ class ConnectBlockUpdatesSpec extends Specification {
def "Extracts updates"() { def "Extracts updates"() {
setup: setup:
def connectBlockUpdates = new ConnectBlockUpdates(Stub(EthereumMultistream)) def connectBlockUpdates = new ConnectBlockUpdates(Stub(EthereumMultistream), Schedulers.boundedElastic())
def block = BlockContainer.from(new BlockJson<TransactionRefJson>().tap { def block = BlockContainer.from(new BlockJson<TransactionRefJson>().tap {
hash = BlockHash.from("0xe5be2159b2b7daf6b126babdcbaa349da668b92d6b8c7db1350fd527fec4885c") hash = BlockHash.from("0xe5be2159b2b7daf6b126babdcbaa349da668b92d6b8c7db1350fd527fec4885c")
number = 13412871 number = 13412871
@@ -71,7 +72,7 @@ class ConnectBlockUpdatesSpec extends Specification {
def "Produce DROP updates for replaced block"() { def "Produce DROP updates for replaced block"() {
setup: setup:
def connectBlockUpdates = new ConnectBlockUpdates(Stub(EthereumMultistream)) def connectBlockUpdates = new ConnectBlockUpdates(Stub(EthereumMultistream), Schedulers.boundedElastic())
def block = BlockContainer.from(new BlockJson<TransactionRefJson>().tap { def block = BlockContainer.from(new BlockJson<TransactionRefJson>().tap {
hash = BlockHash.from("0xe5be2159b2b7daf6b126babdcbaa349da668b92d6b8c7db1350fd527fec4885c") hash = BlockHash.from("0xe5be2159b2b7daf6b126babdcbaa349da668b92d6b8c7db1350fd527fec4885c")
number = 13412871 number = 13412871
@@ -105,7 +106,7 @@ class ConnectBlockUpdatesSpec extends Specification {
def "Gets prev version if available"() { def "Gets prev version if available"() {
setup: setup:
def connectBlockUpdates = new ConnectBlockUpdates(Stub(EthereumMultistream)) def connectBlockUpdates = new ConnectBlockUpdates(Stub(EthereumMultistream), Schedulers.boundedElastic())
def block1 = BlockContainer.from(new BlockJson<TransactionRefJson>().tap { def block1 = BlockContainer.from(new BlockJson<TransactionRefJson>().tap {
hash = BlockHash.from("0xe5be2159b2b7daf6b126babdcbaa349da668b92d6b8c7db1350fd527fec4885c") hash = BlockHash.from("0xe5be2159b2b7daf6b126babdcbaa349da668b92d6b8c7db1350fd527fec4885c")
number = 13412871 number = 13412871
@@ -169,7 +170,7 @@ class ConnectBlockUpdatesSpec extends Specification {
def "Marks old txes as dropped before producing a new version of same block"() { def "Marks old txes as dropped before producing a new version of same block"() {
setup: setup:
def connectBlockUpdates = new ConnectBlockUpdates(Stub(EthereumMultistream)) def connectBlockUpdates = new ConnectBlockUpdates(Stub(EthereumMultistream), Schedulers.boundedElastic())
def block1 = BlockContainer.from(new BlockJson<TransactionRefJson>().tap { def block1 = BlockContainer.from(new BlockJson<TransactionRefJson>().tap {
hash = BlockHash.from("0xe5be2159b2b7daf6b126babdcbaa349da668b92d6b8c7db1350fd527fec4885c") hash = BlockHash.from("0xe5be2159b2b7daf6b126babdcbaa349da668b92d6b8c7db1350fd527fec4885c")
number = 13412871 number = 13412871
@@ -234,7 +235,7 @@ class ConnectBlockUpdatesSpec extends Specification {
def up = Mock(EthereumMultistream) { def up = Mock(EthereumMultistream) {
1 * getHead(Selector.empty) >> head 1 * getHead(Selector.empty) >> head
} }
def connectBlockUpdates = new ConnectBlockUpdates(up) def connectBlockUpdates = new ConnectBlockUpdates(up, Schedulers.boundedElastic())
when: when:
def a1 = connectBlockUpdates.connect() def a1 = connectBlockUpdates.connect()

View File

@@ -24,6 +24,7 @@ import io.emeraldpay.etherjar.domain.TransactionId
import io.emeraldpay.etherjar.hex.Hex32 import io.emeraldpay.etherjar.hex.Hex32
import io.emeraldpay.etherjar.hex.HexData import io.emeraldpay.etherjar.hex.HexData
import reactor.core.publisher.Flux import reactor.core.publisher.Flux
import reactor.core.scheduler.Schedulers
import spock.lang.Specification import spock.lang.Specification
class ConnectLogsSpec extends Specification { class ConnectLogsSpec extends Specification {
@@ -90,7 +91,7 @@ class ConnectLogsSpec extends Specification {
def "Filter is empty"() { def "Filter is empty"() {
setup: setup:
def connectLogs = new ConnectLogs(TestingCommons.emptyMultistream() as EthereumPosMultiStream) def connectLogs = new ConnectLogs(TestingCommons.emptyMultistream() as EthereumPosMultiStream, Schedulers.boundedElastic())
when: when:
def input = Flux.fromIterable([ def input = Flux.fromIterable([
log1, log2, log3, log4 log1, log2, log3, log4
@@ -108,7 +109,7 @@ class ConnectLogsSpec extends Specification {
def "Filter by address"() { def "Filter by address"() {
setup: setup:
def connectLogs = new ConnectLogs(TestingCommons.emptyMultistream() as EthereumPosMultiStream) def connectLogs = new ConnectLogs(TestingCommons.emptyMultistream() as EthereumPosMultiStream, Schedulers.boundedElastic())
when: when:
def input = Flux.fromIterable([ def input = Flux.fromIterable([
log1, log2 log1, log2
@@ -123,7 +124,7 @@ class ConnectLogsSpec extends Specification {
def "Filter by topic"() { def "Filter by topic"() {
setup: setup:
def connectLogs = new ConnectLogs(TestingCommons.emptyMultistream() as EthereumPosMultiStream) def connectLogs = new ConnectLogs(TestingCommons.emptyMultistream() as EthereumPosMultiStream, Schedulers.boundedElastic())
when: when:
def input = Flux.fromIterable([ def input = Flux.fromIterable([
log1, log2, log3, log4 log1, log2, log3, log4
@@ -140,7 +141,7 @@ class ConnectLogsSpec extends Specification {
def "Filter by address and topic"() { def "Filter by address and topic"() {
setup: setup:
def connectLogs = new ConnectLogs(TestingCommons.emptyMultistream() as EthereumPosMultiStream) def connectLogs = new ConnectLogs(TestingCommons.emptyMultistream() as EthereumPosMultiStream, Schedulers.boundedElastic())
when: when:
def input = Flux.fromIterable([ def input = Flux.fromIterable([
log1, log2, log3, log4 log1, log2, log3, log4

View File

@@ -5,6 +5,7 @@ import io.emeraldpay.dshackle.upstream.Head
import io.emeraldpay.dshackle.upstream.Selector import io.emeraldpay.dshackle.upstream.Selector
import io.emeraldpay.dshackle.upstream.ethereum.EthereumMultistream import io.emeraldpay.dshackle.upstream.ethereum.EthereumMultistream
import reactor.core.publisher.Flux import reactor.core.publisher.Flux
import reactor.core.scheduler.Schedulers
import reactor.test.StepVerifier import reactor.test.StepVerifier
import spock.lang.Specification import spock.lang.Specification
@@ -20,7 +21,7 @@ class ConnectNewHeadsSpec extends Specification {
def up = Mock(EthereumMultistream) { def up = Mock(EthereumMultistream) {
1 * getHead(Selector.empty) >> head 1 * getHead(Selector.empty) >> head
} }
ConnectNewHeads connectNewHeads = new ConnectNewHeads(up) ConnectNewHeads connectNewHeads = new ConnectNewHeads(up, Schedulers.boundedElastic())
when: when:
def act1 = connectNewHeads.connect(Selector.empty) def act1 = connectNewHeads.connect(Selector.empty)
def act2 = connectNewHeads.connect(Selector.empty) def act2 = connectNewHeads.connect(Selector.empty)