reactor / BlockHound

Java agent to detect blocking calls from non-blocking threads.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

r2dbc stops working after installing BlockHound

ricardkollcaku opened this issue · comments

Expected Behavior

Im trying to install BlockHound to my reactive app to see if i have blocking calls
i have added BlockHound.install(); in main
I expect r2dbc to work same as without blockhound.
Tell us what you think should happen.

Actual Behavior

when i run the app without BlockHound.install(); and than i make a repository.findAll().subscribe(System.out::printline);
app works perfectly
when i add BlockHound.install(); in my main method
i get this error from r2dbc

2021-04-21 12:47:08.062 ERROR 7807 --- [actor-tcp-nio-2] o.m.r.message.flow.AuthenticationFlow    : Authentication failed

io.r2dbc.spi.R2dbcNonTransientResourceException: Connection unexpectedly closed
	at org.mariadb.r2dbc.client.ClientBase.closedServlet(ClientBase.java:248) ~[r2dbc-mariadb-1.0.0.jar:1.0.0]
	at reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:250) ~[reactor-core-3.4.5.jar:3.4.5]
	at reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:259) ~[reactor-core-3.4.5.jar:3.4.5]
	at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:142) ~[reactor-core-3.4.5.jar:3.4.5]
	at reactor.netty.channel.FluxReceive.onInboundComplete(FluxReceive.java:401) ~[reactor-netty-core-1.0.6.jar:1.0.6]
	at reactor.netty.channel.ChannelOperations.onInboundComplete(ChannelOperations.java:416) ~[reactor-netty-core-1.0.6.jar:1.0.6]
	at reactor.netty.channel.ChannelOperations.terminate(ChannelOperations.java:470) ~[reactor-netty-core-1.0.6.jar:1.0.6]
	at reactor.netty.channel.ChannelOperations.onInboundClose(ChannelOperations.java:431) ~[reactor-netty-core-1.0.6.jar:1.0.6]
	at reactor.netty.channel.ChannelOperationsHandler.channelInactive(ChannelOperationsHandler.java:74) ~[reactor-netty-core-1.0.6.jar:1.0.6]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:262) ~[netty-transport-4.1.63.Final.jar:4.1.63.Final]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:248) ~[netty-transport-4.1.63.Final.jar:4.1.63.Final]
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:241) ~[netty-transport-4.1.63.Final.jar:4.1.63.Final]
	at io.netty.handler.codec.ByteToMessageDecoder.channelInputClosed(ByteToMessageDecoder.java:389) ~[netty-codec-4.1.63.Final.jar:4.1.63.Final]
	at io.netty.handler.codec.ByteToMessageDecoder.channelInactive(ByteToMessageDecoder.java:354) ~[netty-codec-4.1.63.Final.jar:4.1.63.Final]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:262) ~[netty-transport-4.1.63.Final.jar:4.1.63.Final]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:248) ~[netty-transport-4.1.63.Final.jar:4.1.63.Final]
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelInactive(AbstractChannelHandlerContext.java:241) ~[netty-transport-4.1.63.Final.jar:4.1.63.Final]
	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelInactive(DefaultChannelPipeline.java:1405) ~[netty-transport-4.1.63.Final.jar:4.1.63.Final]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:262) ~[netty-transport-4.1.63.Final.jar:4.1.63.Final]
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelInactive(AbstractChannelHandlerContext.java:248) ~[netty-transport-4.1.63.Final.jar:4.1.63.Final]
	at io.netty.channel.DefaultChannelPipeline.fireChannelInactive(DefaultChannelPipeline.java:901) ~[netty-transport-4.1.63.Final.jar:4.1.63.Final]
	at io.netty.channel.AbstractChannel$AbstractUnsafe$8.run(AbstractChannel.java:831) ~[netty-transport-4.1.63.Final.jar:4.1.63.Final]
	at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164) ~[netty-common-4.1.63.Final.jar:4.1.63.Final]
	at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472) ~[netty-common-4.1.63.Final.jar:4.1.63.Final]
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:497) ~[netty-transport-4.1.63.Final.jar:4.1.63.Final]
	at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989) ~[netty-common-4.1.63.Final.jar:4.1.63.Final]
	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.63.Final.jar:4.1.63.Final]
	at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) ~[netty-common-4.1.63.Final.jar:4.1.63.Final]
	at java.base/java.lang.Thread.run(Thread.java:831) ~[na:na]

Steps to Reproduce

Simple project with mariadb and r2dbc

    implementation 'org.springframework.boot:spring-boot-starter-data-r2dbc'
    implementation 'org.springframework.boot:spring-boot-starter-webflux'
    runtimeOnly 'org.mariadb:r2dbc-mariadb'
    runtimeOnly 'org.mariadb.jdbc:mariadb-java-client'
    implementation group: 'io.projectreactor.tools', name: 'blockhound', version: '1.0.6.RELEASE'

application.yml

spring:
  r2dbc:
    url: r2dbc:mariadb://localhost:3306/test?useUnicode=true&characterEncoding=utf8&useSSL=false&useLegacyDatetimeCode=false&serverTimezone=UTC&createDatabaseIfNotExist=true
    username: test
    password: test

simple model and repo that implements ReactiveCrudRepository

and main class:

@SpringBootApplication
public class TestApplication implements CommandLineRunner {
    @Autowired
    TestRepository repository;

    public static void main(String[] args) {
        BlockHound.install();
        SpringApplication.run(SyncApplication.class, args);
    }


    @Override
    public void run(String... args) throws Exception {
        repository.findAll().subscribe(System.out::println);
    }
}
  • Reactor version(s) used: 2.4.5
  • JVM version (azul 11.0.9):
  • OS and version (MacOs Big Sur 11.2.3 (M1 cpu) ):
commented

I don't know exactly which point is blocked, but you can allow blocking as below to operate.
I hope you can solve the blocking.

@AutoService(BlockHoundIntegration.class)
public class CustomBlockHoundIntegration implements BlockHoundIntegration {
  @Override
  public void applyTo(BlockHound.Builder builder) {
    builder
        // allow mariadb client exchange blocking
        .allowBlockingCallsInside(AuthenticationFlow.class.getName(), "exchange");
  }
}

this seems to be a situation in which a specific BlockHound configuration needs to be found, with provided workaround. closing for inactivity