我正在尝试将Kafka的回调制作人发送 API作为未来。即:
def sendFuture[K, V](p: KafkaProducer[K, V], rec: ProducerRecord[K, V]): Future[RecordMetadata] = {
val promise = Promise[RecordMetadata]()
p.send(rec, new Callback {
override def onCompletion(metadata: RecordMetadata, exception: Exception): Unit = {
if (metadata != null) {
promise.complete(Success(metadata))
} else {
promise.complete(Failure(exception))
}
}
})
promise.future
}
我故意禁用Kafka代理,以便生产者在配置的时间(5000毫秒)内保持连接。
在我的测试中,我只等待2秒,并期望看到 TimeoutException 被抛出。
"a producer can't connect to the broker, we " should {
"see timeout when sending messages" in withProducer { p: KafkaProducer[String, String] =>
val rec = new ProducerRecord[String, String](TEST_TOPIC, "testKey", "testValue")
val f = sendFuture(p, rec)
log.info(">> sent and we wait for at most 1 second...")
intercept[TimeoutException] {
Await.ready(f, 2 seconds)
}
log.info(">> TimeoutException intercepted")
}
}
我希望Await等待“ on parallel ”,然后触发 TimeoutException 。 不幸的是,我的测试会失败。 似乎等待,尽管有2秒的界限,但总是等到未来完成而发送的回调失败。 我不太明白原因。
我认为这更多地与Kafka的实现细节有关
当Kafka 发送回调完成Future时,我才会观察到这种行为。
也就是说,将sendFuture
替换为dummyFuture
会通过测试:
def dummyFuture(): Future[Boolean] = {
val promise = Promise[Boolean]()
val thread = new Thread(new Runnable {
override def run(): Unit = {
Thread.sleep(5000)
promise.complete(Success(true))
}
})
thread.start()
promise.future
}
感谢您的帮助。
答案 0 :(得分:0)
我发现我错误地认为send
在它仍在尝试连接时立即返回。 Await不会超时,因为它在 send
达到配置的超时后启动,并在失败时完成了未来。