All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.twitter.finagle.thrift.ThriftClient.scala Maven / Gradle / Ivy

The newest version!
package com.twitter.finagle.thrift

import com.twitter.finagle.client.{Bridge, DefaultClient, DefaultPool}
import com.twitter.finagle.dispatch.SerialClientDispatcher
import com.twitter.finagle.netty3.Netty3Transporter
import com.twitter.finagle.stats.StatsReceiver
import com.twitter.finagle.transport.Transport
import com.twitter.finagle.{Group, Name}
import com.twitter.util.Future
import java.net.SocketAddress
import org.apache.thrift.protocol.TProtocolFactory
import org.jboss.netty.channel.{Channels, ChannelPipelineFactory}

private object ThriftFramedTransportPipelineFactory extends ChannelPipelineFactory {
  def getPipeline() = {
    val pipeline = Channels.pipeline()
    pipeline.addLast("thriftFrameCodec", new ThriftFrameCodec)
    pipeline.addLast("byteEncoder",      new ThriftClientChannelBufferEncoder)
    pipeline.addLast("byteDecoder",      new ThriftChannelBufferDecoder)
    pipeline
  }
}

private[finagle] object ThriftFramedTransporter 
  extends Netty3Transporter[ThriftClientRequest, Array[Byte]](
    name = "thrift",
    pipelineFactory = ThriftFramedTransportPipelineFactory
)

private[finagle] case class ThriftBufferedTransportPipelineFactory(
    protocolFactory: TProtocolFactory
) extends ChannelPipelineFactory {
  def getPipeline() = {
    val pipeline = ThriftFramedTransportPipelineFactory.getPipeline()
    pipeline.replace(
      "thriftFrameCodec", "thriftBufferDecoder",
      new ThriftBufferDecoder(protocolFactory))
    pipeline
  }
}

class ThriftBufferedTransporter(protocolFactory: TProtocolFactory)
  extends Netty3Transporter[ThriftClientRequest, Array[Byte]](
    name = "thrift",
    pipelineFactory = ThriftBufferedTransportPipelineFactory(protocolFactory)
)

object ThriftBufferedTransporter {
  def apply(protocolFactory: TProtocolFactory): ThriftBufferedTransporter =
    new ThriftBufferedTransporter(protocolFactory)
}

/**
 * A Finagle Client for [[http://thrift.apache.org Apache Thrift]].
 *
 * The client uses the standard thrift protocols, with support for
 * both framed and buffered transports. Finagle attempts to upgrade
 * the protocol in order to ship an extra envelope carrying trace IDs
 * and client IDs associated with the request. These are used by
 * Finagle's tracing facilities and may be collected via aggregators
 * like [[http://twitter.github.com/zipkin/ Zipkin]].
 *
 * The negotiation is simple: on connection establishment, an
 * improbably-named method is dispatched on the server. If that
 * method isn't found, we are dealing with a legacy thrift server,
 * and the standard protocol is used. If the remote server is also a
 * finagle server (or any other supporting this extension), we reply
 * to the request, and every subsequent request is dispatched with an
 * envelope carrying trace metadata. The envelope itself is also a 
 * Thrift struct described [[https://github.com/twitter/finagle/blob/master/finagle-thrift/src/main/thrift/tracing.thrift here]].
 */
class ThriftClient(
    transporter: (SocketAddress, StatsReceiver) => 
      Future[Transport[ThriftClientRequest, Array[Byte]]],
    protocolFactory: TProtocolFactory,
    serviceName: String = "unknown",
    clientId: Option[ClientId] = None
) extends DefaultClient[ThriftClientRequest, Array[Byte]](
    name = "thrift",
    endpointer = {
      // The preparer performs the protocol upgrade.
      val preparer = ThriftClientPreparer(protocolFactory, serviceName, clientId)
      val bridged = Bridge[ThriftClientRequest, Array[Byte], ThriftClientRequest, Array[Byte]](
        transporter, new SerialClientDispatcher(_))
      (sa, sr) => preparer.prepare(bridged(sa, sr))
    },
    pool = DefaultPool[ThriftClientRequest, Array[Byte]]()
) {

  protected def superNewClient(dest: Name, label: String) = super.newClient(dest, label)

  override def newClient(dest: Name, label: String) =
    if (label.nonEmpty)
      new ThriftClient(transporter, protocolFactory, label, clientId).superNewClient(dest, label)
    else
      superNewClient(dest, label)
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy