3

サーバーとクライアントのコードを生成するために 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 のリサイクル クライアントをどのように閉鎖するのですか? 明らかな何かが欠けているように感じます。

4

2 に答える 2

7

私の知る限り、automagicThrift.newIface[Iface]メソッドを使用してサービスを作成すると、それを閉じることはできません。これは、結果の値についてコードが知っているのは、それが に準拠しているということだけだからIfaceです。閉じる必要がある場合は、クライアントを 2 つの手順でインスタンス化できます。1 つは Thrift サービスを作成し、もう 1 つはそれをインターフェイスに適応させます。

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でこれを試しましたが、うまくいきました。軽く編集されたトランスクリプトを次に示します。

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

これはそれほど悪くはありませんが、私がまだ知らないより良い方法があることを願っています.

于 2016-01-16T08:19:21.413 に答える
0

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)
  }
于 2016-01-16T07:26:33.357 に答える