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

com.twitter.finagle.channel.BrokerChannelHandler.scala Maven / Gradle / Ivy

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

/**
 * Dispatches channel events to a {{com.twitter.concurrent.Broker}}.
 */

import org.jboss.netty.channel._

import com.twitter.concurrent.{Broker, Offer}

class BrokerChannelHandler extends SimpleChannelHandler {
  sealed trait Event {
    type E <: ChannelEvent
    val e: E
    val ctx: ChannelHandlerContext

  }

  sealed trait UpstreamEvent extends Event {
    def sendUpstream() {
      ctx.sendUpstream(e)
    }
  }

  case class Message(e: MessageEvent, ctx: ChannelHandlerContext)
    extends UpstreamEvent { type E = MessageEvent }
  case class WriteComplete(e: WriteCompletionEvent, ctx: ChannelHandlerContext)
    extends UpstreamEvent { type E = WriteCompletionEvent }
  case class ChildOpen(e: ChildChannelStateEvent, ctx: ChannelHandlerContext)
    extends UpstreamEvent { type E = ChildChannelStateEvent }
  case class ChildClosed(e: ChildChannelStateEvent, ctx: ChannelHandlerContext)
    extends UpstreamEvent { type E = ChildChannelStateEvent }
  case class Open(e: ChannelStateEvent, ctx: ChannelHandlerContext)
    extends UpstreamEvent { type E = ChannelStateEvent }
  case class Closed(e: ChannelStateEvent, ctx: ChannelHandlerContext)
    extends UpstreamEvent { type E = ChannelStateEvent }
  case class Bound(e: ChannelStateEvent, ctx: ChannelHandlerContext)
    extends UpstreamEvent { type E = ChannelStateEvent }
  case class Unbound(e: ChannelStateEvent, ctx: ChannelHandlerContext)
    extends UpstreamEvent { type E = ChannelStateEvent }
  case class Connected(e: ChannelStateEvent, ctx: ChannelHandlerContext)
    extends UpstreamEvent { type E = ChannelStateEvent }
  case class Disconnected(e: ChannelStateEvent, ctx: ChannelHandlerContext)
    extends UpstreamEvent { type E = ChannelStateEvent }
  case class InterestChanged(e: ChannelStateEvent, ctx: ChannelHandlerContext)
    extends UpstreamEvent { type E = ChannelStateEvent }
  case class Exception(e: ExceptionEvent, ctx: ChannelHandlerContext)
    extends UpstreamEvent { type E = ExceptionEvent }

  object MessageValue {
    def unapply(e: UpstreamEvent): Option[(Any, ChannelHandlerContext)] = e match {
      case Message(e, ctx) => Some((e.getMessage, ctx))
      case _ => None
    }
  }

  sealed trait DownstreamEvent extends Event {
    def sendDownstream() {
      ctx.sendDownstream(e)
    }
  }

  case class Write(e: MessageEvent, ctx: ChannelHandlerContext)
    extends DownstreamEvent { type E = MessageEvent }
  case class Bind(e: ChannelStateEvent, ctx: ChannelHandlerContext)
    extends DownstreamEvent { type E = ChannelStateEvent }
  case class Connect(e: ChannelStateEvent, ctx: ChannelHandlerContext)
    extends DownstreamEvent { type E = ChannelStateEvent }
  case class InterestOps(e: ChannelStateEvent, ctx: ChannelHandlerContext)
    extends DownstreamEvent { type E = ChannelStateEvent }
  case class Disconnect(e: ChannelStateEvent, ctx: ChannelHandlerContext)
    extends DownstreamEvent { type E = ChannelStateEvent }
  case class Unbind(e: ChannelStateEvent, ctx: ChannelHandlerContext)
    extends DownstreamEvent { type E = ChannelStateEvent }
  case class Close(e: ChannelStateEvent, ctx: ChannelHandlerContext)
    extends DownstreamEvent { type E = ChannelStateEvent }

  object WriteValue {
    def unapply(e: DownstreamEvent): Option[(Any, ChannelHandlerContext)] = e match {
      case Write(e, ctx) => Some((e.getMessage, ctx))
      case _ => None
    }
  }

  /**
   * Proxy further downstream events.
   */
  protected def proxyDownstream() {
    downstreamEvent foreach { _.sendDownstream() }
  }

  /**
   * Proxy further upstream events.
   */
  protected def proxyUpstream() {
    upstreamEvent foreach { _.sendUpstream() }
  }
  
  /**
   * Proxy both upstream & downstream events.
   */
  protected def proxy() {
    proxyUpstream()
    proxyDownstream()
  }

  val upstreamBroker = new Broker[UpstreamEvent]
  val upstreamEvent: Offer[UpstreamEvent] = upstreamBroker.recv

  val downstreamBroker = new Broker[DownstreamEvent]
  val downstreamEvent: Offer[DownstreamEvent] = downstreamBroker.recv

  /* Upstream */
  override def messageReceived(ctx: ChannelHandlerContext, e: MessageEvent) {
    upstreamBroker ! Message(e, ctx)
  }


  override def exceptionCaught(ctx: ChannelHandlerContext, e: ExceptionEvent) {
    // Exceptions are special: we always want to make sure we handle
    // them, so we're stricter: the receiver must synchronize immediately,
    // otherwise we proxy it upstream.
    //
    // This makes sure that exceptions always get propagated, even if 
    // the channel handler process has died (eg. it threw an unhandled
    // exception).
    val of = upstreamBroker.send(Exception(e, ctx)) orElse Offer.const {
      super.exceptionCaught(ctx, e)
    }
    of.sync()
  }

  override def channelOpen(ctx: ChannelHandlerContext, e: ChannelStateEvent) {
    upstreamBroker ! Open(e, ctx)
  }

  override def channelBound(ctx: ChannelHandlerContext, e: ChannelStateEvent) {
    upstreamBroker ! Bound(e, ctx)
  }

  override def channelConnected(ctx: ChannelHandlerContext, e: ChannelStateEvent) {
    upstreamBroker ! Connected(e, ctx)
  }

  override def channelInterestChanged(ctx: ChannelHandlerContext, e: ChannelStateEvent) {
    upstreamBroker ! InterestChanged(e, ctx)
  }

  override def channelDisconnected(ctx: ChannelHandlerContext, e: ChannelStateEvent) {
    upstreamBroker ! Disconnected(e, ctx)
  }

  override def channelUnbound(ctx: ChannelHandlerContext, e: ChannelStateEvent) {
    upstreamBroker ! Unbound(e, ctx)
  }

  override def channelClosed(ctx: ChannelHandlerContext, e: ChannelStateEvent) {
    upstreamBroker ! Closed(e, ctx)
  }

  override def writeComplete(ctx: ChannelHandlerContext, e: WriteCompletionEvent) {
    upstreamBroker ! WriteComplete(e, ctx)
  }

  override def childChannelOpen(ctx: ChannelHandlerContext, e: ChildChannelStateEvent) {
    upstreamBroker ! ChildOpen(e, ctx)
  }

  override def childChannelClosed(ctx: ChannelHandlerContext, e: ChildChannelStateEvent) {
    upstreamBroker ! ChildClosed(e, ctx)
  }

  /* Downstream */

  override def writeRequested(ctx: ChannelHandlerContext, e: MessageEvent) {
    downstreamBroker ! Write(e, ctx)
  }

  override def bindRequested(ctx: ChannelHandlerContext, e: ChannelStateEvent) {
    downstreamBroker ! Bind(e, ctx)
  }

  override def connectRequested(ctx: ChannelHandlerContext, e: ChannelStateEvent) {
    downstreamBroker ! Connect(e, ctx)
  }

  override def setInterestOpsRequested(ctx: ChannelHandlerContext, e: ChannelStateEvent) {
    downstreamBroker ! InterestOps(e, ctx)
  }

  override def disconnectRequested(ctx: ChannelHandlerContext, e: ChannelStateEvent) {
    downstreamBroker ! Disconnect(e, ctx)
  }

  override def unbindRequested(ctx: ChannelHandlerContext, e: ChannelStateEvent) {
    downstreamBroker ! Unbind(e, ctx)
  }

  override def closeRequested(ctx: ChannelHandlerContext, e: ChannelStateEvent) {
    downstreamBroker ! Close(e, ctx)
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy