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

com.twitter.finagle.netty4.Netty4Transporter.scala Maven / Gradle / Ivy

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

import com.twitter.finagle.client.Transporter
import com.twitter.finagle.decoder.Framer
import com.twitter.finagle.netty4.channel._
import com.twitter.finagle.netty4.transport.ChannelTransport
import com.twitter.finagle.transport.{Transport, TransportContext}
import com.twitter.finagle.Stack
import com.twitter.io.Buf
import com.twitter.util.Future
import io.netty.channel._
import java.net.SocketAddress

object Netty4Transporter {

  /**
   * A [[com.twitter.finagle.Stack.Param]] used to configure the ability to
   * exert backpressure by only reading from the Channel when the [[Transport]] is
   * read.
   */
  private[finagle] case class Backpressure(backpressure: Boolean) {
    def mk(): (Backpressure, Stack.Param[Backpressure]) = (this, Backpressure.param)
  }

  private[finagle] object Backpressure {
    implicit val param: Stack.Param[Backpressure] =
      Stack.Param(Backpressure(backpressure = true))
  }

  private[this] def build[In, Out, Ctx <: TransportContext](
    init: ChannelInitializer[Channel],
    addr: SocketAddress,
    params: Stack.Params,
    transportFactory: Channel => Transport[Any, Any] {
      type Context <: Ctx
    }
  )(
    implicit mOut: Manifest[Out]
  ): Transporter[In, Out, Ctx] = new Transporter[In, Out, Ctx] {

    private[this] val factory = new ConnectionBuilder(init, addr, params)

    def remoteAddress: SocketAddress = addr

    def apply(): Future[Transport[In, Out] { type Context <: Ctx }] = factory.build { ch =>
      Future {
        Transport
          .cast[In, Out](transportFactory(ch))
          .asInstanceOf[Transport[In, Out] { type Context <: Ctx }]
      }
    }

    override def toString: String = "Netty4Transporter"
  }

  /**
   * `Transporter` constructor for protocols that need direct access to the netty pipeline
   * (ie; finagle-http)
   *
   * @note this factory method makes no assumptions about reference counting
   *       of `ByteBuf` instances.
   */
  def raw[In, Out, Ctx <: TransportContext](
    pipelineInit: ChannelPipeline => Unit,
    addr: SocketAddress,
    params: Stack.Params,
    transportFactory: Channel => Transport[Any, Any] {
      type Context <: Ctx
    }
  )(
    implicit mOut: Manifest[Out]
  ): Transporter[In, Out, Ctx] = {
    val init = new RawNetty4ClientChannelInitializer(pipelineInit, params)

    build[In, Out, Ctx](init, addr, params, transportFactory)
  }

  /**
   * `Transporter` constructor for protocols that need direct access to the netty pipeline
   * (ie; finagle-http)
   *
   * @note this factory method makes no assumptions about reference counting
   *       of `ByteBuf` instances.
   */
  def raw[In, Out](
    pipelineInit: ChannelPipeline => Unit,
    addr: SocketAddress,
    params: Stack.Params
  )(
    implicit mOut: Manifest[Out]
  ): Transporter[In, Out, TransportContext] = {
    val init = new RawNetty4ClientChannelInitializer(pipelineInit, params)

    build[In, Out, TransportContext](init, addr, params, new ChannelTransport(_))
  }

  /**
   * `Transporter` constructor for protocols which are entirely implemented in
   * dispatchers (ie; finagle-mux, finagle-mysql) and expect c.t.io.Bufs
   *
   * @note this factory method will install the `DirectToHeapInboundHandler` which
   *       copies all direct `ByteBuf`s to heap allocated `ByteBuf`s and frees the
   *       direct buffer.
   */
  def framedBuf(
    framerFactory: Option[() => Framer],
    addr: SocketAddress,
    params: Stack.Params
  ): Transporter[Buf, Buf, TransportContext] = {
    val init = new Netty4ClientChannelInitializer(params, framerFactory)

    build[Buf, Buf, TransportContext](init, addr, params, new ChannelTransport(_))
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy