mauricio / postgresql-async

Async, Netty based, database drivers for PostgreSQL and MySQL written in Scala
Apache License 2.0
1.43k stars 222 forks source link

PostgreSQLConnection.connect blocks for almost 6 seconds, even though it returns a Future #222

Open sp-1234 opened 7 years ago

sp-1234 commented 7 years ago

I tried this code (in Kotlin, but I guess it shouldn't matter), All it does: creates PostgreSQLConnection with all default values, calls connect method on it, does nothing with the returned Future, and measures elapsed time. If this call has to be blocking then maybe there's little point in returning Future because it doesn't save anything here, or maybe it's just a bug.

import com.github.mauricio.async.db.postgresql.PostgreSQLConnection
import com.github.mauricio.async.db.postgresql.column.PostgreSQLColumnDecoderRegistry
import com.github.mauricio.async.db.postgresql.column.PostgreSQLColumnEncoderRegistry
import com.github.mauricio.async.db.postgresql.util.URLParser
import com.github.mauricio.async.db.util.ExecutorServiceUtils
import com.github.mauricio.async.db.util.NettyUtils
import kotlin.system.measureTimeMillis

fun main(args: Array<String>) {
    println(measureTimeMillis {
        PostgreSQLConnection(
                URLParser.DEFAULT(),
                PostgreSQLColumnEncoderRegistry.Instance(),
                PostgreSQLColumnDecoderRegistry.Instance(),
                NettyUtils.DefaultEventLoopGroup(),
                ExecutorServiceUtils.CachedExecutionContext()
        ).connect()
    }) // prints something close to 5862 on my machine
}

I can translate it to Scala if you wish, that's not a big deal.

I'm using this library version: 'postgresql-async_2.12', version: "0.2.21"

sp-1234 commented 7 years ago

Also I noticed that it blocks a thread for such a long time only the first time. Subsequent connections (construction of PostgreSQLConnection + connect call) only block for ~0.45ms, so it's probably OK for long running services.

Still it's interesting what exactly is happening at first connect.

fwbrasil commented 7 years ago

Probably related to https://github.com/mauricio/postgresql-async/issues/91

mauricio commented 7 years ago

Not really, connect doesn't block, only if using a pool. The actual connect operation just sets up netty and the channels: https://github.com/mauricio/postgresql-async/blob/master/postgresql-async/src/main/scala/com/github/mauricio/async/db/postgresql/codec/PostgreSQLConnectionHandler.scala#L82-L104

mauricio commented 7 years ago

@sp-1234 none of the tests take this long to run: https://travis-ci.org/mauricio/postgresql-async/jobs/228756072 (other than the pool test, that has to timeout to it takes longer), not sure how this would be related to connection and be faster after the first since every connection will cause a new TCP connection to happen.

sp-1234 commented 7 years ago

Maybe it's a platform specific issue, I were doing it on macOS. But this all is true story.

njeuk commented 7 years ago

@sp-1234 This is caused by an issue with osx DNS resolution, discussed here https://github.com/netty/netty/issues/6454 with resolutions https://stackoverflow.com/questions/39636792/jvm-takes-a-long-time-to-resolve-ip-address-for-localhost/39698914#39698914 . Adding my hostname explicitly to hosts worked well for me.