Note: the most up-to-date examples are located in the finatra/examples project.

See examples/thrift-server for an example Thrift Server.

Thrift Server Definition

To start, add a dependency on the finatra-thrift library. We also recommend using Logback as your SLF4J implementation. E.g.,

with sbt:

"com.twitter" %% "finatra-thrift" % "17.12.0"
"ch.qos.logback" % "logback-classic" % versions.logback,

For more information on logging with Finatra see: Introduction to Logging With Finatra.

Create a new class that extends c.t.finatra.thrift.ThriftServer:

import com.twitter.finatra.thrift.ThriftServer
import com.twitter.finatra.thrift.routing.ThriftRouter

object ExampleServerMain extends ExampleServer

class ExampleServer extends ThriftServer {

  override def configureThrift(router: ThriftRouter): Unit = {
    ???
  }
}

A more complete example includes adding Modules, a Controller, and Filters.

import DoEverythingModule
import com.twitter.finatra.thrift.ThriftServer
import com.twitter.finatra.thrift.routing.ThriftRouter

object ExampleServerMain extends ExampleServer

class ExampleServer extends ThriftServer {

  override val modules = Seq(
    DoEverythingModule)

  override def configureThrift(router: ThriftRouter): Unit = {
    router
      .filter[LoggingMDCFilter]
      .filter[TraceIdMDCFilter]
      .add[ExampleThriftController]
  }
}

This should look familiar as the structure is similar to creating an HttpServer. The server can be thought of as a collection of controllers composed with filters. Additionally, a server can define modules for providing instances to the object graph.

Naming Convention

The Finatra convention is to create a Scala object with a name ending in “Main” that extends your server class. The server class can be used in testing as this allows your server to be instantiated multiple times in tests without worrying about static state persisting across test runs in the same JVM. The static object, e.g., ExampleServerMain, which contains the static main method for the server would then be used as the application entry point for running the server in all other cases.

Override Default Behavior

Flags

Some deployment environments may make it difficult to set Flag values with command line arguments. If this is the case, Finatra’s ThriftServer‘s core flags can be set from code.

For example, instead of setting the -thrift.port flag, you can override the following method in your server.

class ExampleServer extends ThriftServer {

  override val defaultFinatraThriftPort: String = ":9090"

  override def configureThrift(router: ThriftRouter): Unit = {
    ...
  }
}

For a list of what flags can be set programmatically, please see the ThriftServer class.

For more information on using and setting command-line flags see Flags.

Finagle Server Configuration

If you want to further configure the underlying Finagle server you can override configureThriftServer in your server to set additional configuration on, or override the default configuration of your server.

For example:

class ExampleServer extends ThriftServer {

  override def configureThrift(router: ThriftRouter): Unit = {
    ...
  }

  override def configureThriftServer(server: ThriftMux.Server): ThriftMux.Server = {
    server
      .withMaxRequestSize(...)
      .withAdmissionControl.concurrencyLimit(
        maxConcurrentRequests = ...,
        maxWaiters = ...)
  }
}

For more information on Finagle server configuration see the documentation here; specifically the server documentation here.