[Bug] Selector threads not shutdown on initialization exception


#1

I’ve discovered a bug with the java AsyncClient. If the constructor throws an exception (e.g. if all the hosts are unreachable), then it does not shutdown the selector threads. When attempting to re-initialize the client (using the same AsyncPolicy) it will start a new set of selector threads each time that are not shut down.

Here is a simple test I wrote in Scala to demonstrate the issue:

import com.aerospike.client.async.{AsyncClient, AsyncClientPolicy}
import com.aerospike.client.{AerospikeException, Host}
import org.scalatest.{Matchers, WordSpec}

import scala.collection.JavaConverters._

class AerospikeAsyncClientTest extends WordSpec with Matchers {

  val hosts = Seq(new Host("foobar", 12345))
  val asyncClientPolicy = new AsyncClientPolicy()
  asyncClientPolicy.asyncSelectorThreads = 10

  def getSelectorThreads = Thread.getAllStackTraces.keySet.asScala.filter(_.getName.startsWith("selector"))

  "The Aerospike AsyncClient" should {
    "shutdown selector threads on initialization exception" in {
      val initialNumSelectorThreads = getSelectorThreads.size

      initialNumSelectorThreads should equal(0) // passes

      for (i <- 1 to 10) {
        an[AerospikeException] should be thrownBy {
          new AsyncClient(asyncClientPolicy, hosts: _*)
        }
      }

      getSelectorThreads.size should equal(initialNumSelectorThreads) // fails: 100 did not equal 0
    }
  }
}

This issue still exists in the latest version of the java client (3.2.5).


#2

Yes, that is a bug. We will fix in the next java client release.


#3

Ideally it would be nice if the AsyncClient constructor only threw exceptions on non-recoverable failures, and in cases like this could re-try the connection internally. It seems to handle this case fine in the event that connectivity is temporarily lost to Aerospike servers after construction.


#4

The client already supports reconnection if initial connection fails. Just set ClientPolicy.failIfNotConnected to false.