我如何关闭 Finagle Thrift 客户端?
How do I close a Finagle Thrift client?
我正在使用 scrooge + thrift 来生成我的服务器和客户端代码。目前一切正常。
这是我如何使用我的客户端的一个简单示例:
private lazy val client =
Thrift.newIface[MyPingService[Future]](s"$host:$port")
def main(args: Array[String]): Unit = {
logger.info("ping!")
client.ping().foreach { _ =>
logger.info("pong!")
// TODO: close client
sys.exit(0)
}
}
一切正常,但是当程序退出时服务器抱怨未关闭的连接。我已经看遍了,但似乎无法弄清楚如何关闭 client
实例。
所以我的问题是,如何关闭 Finagle thrift 客户端?我觉得我错过了一些明显的东西。
我没用过 finagle,但是根据 Finagle 文档
val product = client().flatMap { service =>
// `service` is checked out from the pool.
service(QueryRequest("SELECT 5*5 AS `product`")) map {
case rs: ResultSet => rs.rows.map(processRow)
case _ => Seq.empty
} ensure {
// put `service` back into the pool.
service.close()
}
}
你能不能采用类似的策略
client.ping().foreach { service =>
logger.info("pong!")
// TODO: close client
service.close()
sys.exit(0)
}
据我所知,当你使用 automagic Thrift.newIface[Iface]
方法创建你的服务时,你不能关闭它,因为你的代码唯一知道结果值的是它符合至 Iface
。如果您需要关闭它,您可以分两步实例化您的客户端,一步创建 Thrift 服务,另一步使其适应您的界面。
如果您使用 Scrooge 生成您的 Thrift 界面,它会是这样的:
val serviceFactory: ServiceFactory[ThriftClientRequest,Array[Byte]] =
Thrift.newClient(s"$host:$port")
val client: MyPingService[Future] =
new MyPingService.FinagledClient(serviceFactory.toService)
doStuff(client).ensure(serviceFactory.close())
我在 repl 中试过这个,它对我有用。这是 lightly-edited 抄本:
scala> val serviceFactory = Thrift.newClient(...)
serviceFactory: ServiceFactory[ThriftClientRequest,Array[Byte]] = <function1>
scala> val tweetService = new TweetService.FinagledClient(serviceFactory.toService)
tweetService: TweetService.FinagledClient = TweetService$FinagledClient@20ef6b76
scala> Await.result(tweetService.getTweets(GetTweetsRequest(Seq(20))))
res7: Seq[GetTweetResult] = ... "just setting up my twttr" ...
scala> serviceFactory.close
res8: Future[Unit] = ConstFuture(Return(()))
scala> Await.result(tweetService.getTweets(GetTweetsRequest(Seq(20))))
com.twitter.finagle.ServiceClosedException
这还不错,但我希望有更好的方法,我还不知道。
我正在使用 scrooge + thrift 来生成我的服务器和客户端代码。目前一切正常。
这是我如何使用我的客户端的一个简单示例:
private lazy val client =
Thrift.newIface[MyPingService[Future]](s"$host:$port")
def main(args: Array[String]): Unit = {
logger.info("ping!")
client.ping().foreach { _ =>
logger.info("pong!")
// TODO: close client
sys.exit(0)
}
}
一切正常,但是当程序退出时服务器抱怨未关闭的连接。我已经看遍了,但似乎无法弄清楚如何关闭 client
实例。
所以我的问题是,如何关闭 Finagle thrift 客户端?我觉得我错过了一些明显的东西。
我没用过 finagle,但是根据 Finagle 文档
val product = client().flatMap { service =>
// `service` is checked out from the pool.
service(QueryRequest("SELECT 5*5 AS `product`")) map {
case rs: ResultSet => rs.rows.map(processRow)
case _ => Seq.empty
} ensure {
// put `service` back into the pool.
service.close()
}
}
你能不能采用类似的策略
client.ping().foreach { service =>
logger.info("pong!")
// TODO: close client
service.close()
sys.exit(0)
}
据我所知,当你使用 automagic Thrift.newIface[Iface]
方法创建你的服务时,你不能关闭它,因为你的代码唯一知道结果值的是它符合至 Iface
。如果您需要关闭它,您可以分两步实例化您的客户端,一步创建 Thrift 服务,另一步使其适应您的界面。
如果您使用 Scrooge 生成您的 Thrift 界面,它会是这样的:
val serviceFactory: ServiceFactory[ThriftClientRequest,Array[Byte]] =
Thrift.newClient(s"$host:$port")
val client: MyPingService[Future] =
new MyPingService.FinagledClient(serviceFactory.toService)
doStuff(client).ensure(serviceFactory.close())
我在 repl 中试过这个,它对我有用。这是 lightly-edited 抄本:
scala> val serviceFactory = Thrift.newClient(...)
serviceFactory: ServiceFactory[ThriftClientRequest,Array[Byte]] = <function1>
scala> val tweetService = new TweetService.FinagledClient(serviceFactory.toService)
tweetService: TweetService.FinagledClient = TweetService$FinagledClient@20ef6b76
scala> Await.result(tweetService.getTweets(GetTweetsRequest(Seq(20))))
res7: Seq[GetTweetResult] = ... "just setting up my twttr" ...
scala> serviceFactory.close
res8: Future[Unit] = ConstFuture(Return(()))
scala> Await.result(tweetService.getTweets(GetTweetsRequest(Seq(20))))
com.twitter.finagle.ServiceClosedException
这还不错,但我希望有更好的方法,我还不知道。