Isabel Martin


Posted December 12, 2017

⛄ December 2017 Release Notes - Version 17.12.0

The December release has arrived!

Finagle 17.12.0, Finatra 17.12.0, Scrooge 17.12.0, TwitterServer 17.12.0, and Util 17.12.0.


New Features:

  • finagle-core: Expose Tunables for MethodBuilder timeout configuration. Update the http.MethodBuilder and thriftmux.MethodBuilder to accept Tunables for configuring total and per-request timeouts. c912dd4b

  • finagle-thrift, finagle-thriftmux: Add support for Scrooge ReqRepServicePerEndpoint functionality. df5f10bd

  • finagle-thriftmux: Add support for Scrooge ServicePerEndpoint and ReqRepServicePerEndpoint functionality to thriftmux.MethodBuilder. 3abaa524

Breaking API Changes:

  • finagle-base-http: Remove deprecated [Request|Response].[encode|decode][Bytes|String] methods. Use c.t.f.h.codec.HttpCodec methods instead. 006de6a3

  • finagle-thrift: Move ThriftRichClient and ThriftRichServer to c.t.finagle.thrift package. fcf66bae

Runtime Behavior Changes:

  • finagle-core: The “pipelining/pending” stat has been removed from protocols using c.t.f.dispatch.PipeliningClientDispatcher. Refer to the “pending” stat for the number of outstanding requests. 0d162d17

  • finagle-thrift,thriftmux: Tracing of RPC method names has been removed. This concern has moved into Scrooge. df161758



  • finatra-thrift: Add tests for new Scrooge ReqRepServicePerEndpoint functionalty. b8e919d3


  • finatra-http: add a multipart = true arg to EmbeddedHttpServer.httpMultipartFormPost. c139d95
  • inject-sever: Do not use the c.t.inject.server.EmbeddedTwitterServer InMemoryStatsReceiver for embedded http clients. The http client stats are emitted with the server under test stats which can be confusing, thus we now create a new InMemoryStatsReceiver when creating an embedded http client. 0c4a8ee5


API Changes:

  • util-collection: c.t.util.SetMaker has been removed. Direct usage of Guava is recommended if needed. b8bd0d4f


  • scrooge: Introduce scrooge.Request and scrooge.Response envelopes which are used in ReqRepServicePerEndpoint interfaces and associated code. The scrooge Request and Response allow for passing “header” information (via ThriftMux Message contexts) between clients and servers. For instance, a server can implement a ReqRepServicePerEndpoint, and set response headers along with a method response, e.g.,
  class MyService extends MyService.ReqRepServicePerEndpoint {

    def foo: Service[Request[Foo.Args], Response[Foo.SuccessType]] = {[Request[Foo.Args], Response[Foo.SuccessType]] { request: Request[Foo.Args] =>
        val result = ... // computations
              headers = Map("" -> Seq(Buf.Utf8("value1"))),

This ServicePerEndpoint can then be served using ThriftMux:

  ThriftMux.server.serveIface(":9999", new MyService().toThriftService)

These response headers will be transported as Mux#contexts to the client. If the client is using the client-side ReqRepServicePerEndpoint it will be able to read the headers from the returned Response directly. E.g.,

  val client = ThriftMux.client.reqRepServicePerEndpoint[MyService.ReqRepServicePerEndpoint]

  val response: Response[Foo.SuccessType] = Await.result(

  if (response.headers.contains("")) {

Users can also choose to wrap the ReqRepServicePerEndpoint with a MethodPerEndpoint via ThriftMux.client.reqRepMethodPerEndpoint(reqRepServicePerEndpoint) in order to deal with methods instead of services. See the scrooge documentation for more information. aa1fb0c0

Twitter Server

Bug Fixes:

  • Treat as an idle thread on “/admin/threads”. This method is observed when using Netty 4’s native transport. f8f64a46