colossus

service

package service

Visibility
  1. Public
  2. All

Type Members

  1. class AsyncHandlerGenerator[I, O] extends AnyRef

    So we need to take a type-parameterized request object, package it into a monomorphic case class to send to the worker, and have the handler that receives that object able to pattern match out the parameterized object, all without using reflection.

    So we need to take a type-parameterized request object, package it into a monomorphic case class to send to the worker, and have the handler that receives that object able to pattern match out the parameterized object, all without using reflection. We can do that with some nifty path-dependant types

  2. trait AsyncServiceClient[I, O] extends AnyRef

  3. class BasicServiceDelegator[C <: CodecDSL] extends DSLDelegator[C]

  4. class BasicServiceHandler[C <: CodecDSL] extends ServiceServer[service.BasicServiceHandler.C.Input, service.BasicServiceHandler.C.Output] with DSLHandler[C]

  5. trait Callback[+O] extends AnyRef

    A Callback is a Monad for doing in-thread non-blocking operations.

    A Callback is a Monad for doing in-thread non-blocking operations. It is essentially a "function builder" that uses function composition to chain together a callback function that is eventually passed to another function.

    Normally if you have a function that requires a callback, the function looks something like:

    def doSomething(param, param, callBack: result => Unit)

    and then you'd call it like

    doSomething(arg1, arg2, result => println("got the result"))

    This is the well-known continuation pattern, and it something we'd like to avoid due to the common occurrance of deeply nested "callback hell". Instead, the Callback allows us to define out function as

    def doSomething(param1, param2): Callback[Result]

    and call it like

    val c = doSomething(arg1, arg2)
    c.map{ result =>
      println("got the result")
    }.execute()

    Thus, in practice working with Callbacks is very similar to working with Futures. The big differences from a future are:

    1. Callbacks are not thread safe at all. They are entirely intended to stay inside a single worker. Otherwise just use Futures.

    2. The execute() method needs to be called once the callback has been fully built, which unlike futures requires some part of the code to know when a callback is ready to be invoked

    Using Callbacks in Services

    When building services, particularly when working with service clients, you will usually be getting Callbacks back from clients when requests are sent. *Do not call execute yourself!* on these Callbacks. They must be returned as part of request processing, and Colossus will invoke the callback itself.

    Using Callbacks elsewhere

    If you are using Callbacks in some custom situation outside of services, be aware that exceptions thrown inside a map or flatMap are properly caught and can be recovered using recover and recoverWith, however exceptions thrown in the "final" handler passed to execute are not caught. This is because the final block cannot be mapped on (since it is only passed when the callback is executed) and throwing the exception is preferrable to suppressing it.

    Any exception that is thrown in this block is however rethrown as a CallbackExecutionException. Therefore, any "trigger" function you wrap inside a callback should properly catch this exception.

  6. case class CallbackExec(cb: () ⇒ Unit, in: Option[FiniteDuration] = None) extends Product with Serializable

  7. trait CallbackExecution extends Actor with ActorLogging

  8. class CallbackExecutionException extends Exception

    This exception is only thrown when there's a uncaught exception in the execution block of a Callback.

    This exception is only thrown when there's a uncaught exception in the execution block of a Callback. For example,

    val c: Callback[Foo] = getCallback()
    c.execute{
      case Success(foo) => throw new Exception("exception")
    }

    will result in a CallbackExecutionException being thrown, however

    c.map{_ => throw new Exception("exception")}.execute()

    will not because the exception can still be recovered

  9. case class CallbackExecutor(context: ExecutionContext, executor: ActorRef) extends Product with Serializable

    A CallbackExecutor is an actor that mixes in the [CallbackExecution] trait to complete the execution of a [Callback] that has been converted from a Future.

    A CallbackExecutor is an actor that mixes in the [CallbackExecution] trait to complete the execution of a [Callback] that has been converted from a Future. In almost every case, the executor should be an actor running in a Pinned Dispatcher and shound be the same actor that created the original Callback, for example, a Colossus worker.

    This type is generally only needed when converting a Future to a Callback, or scheduling a Callback for delayed execution.

  10. trait ClientCodecProvider[C <: CodecDSL] extends AnyRef

  11. case class ClientConfig(address: InetSocketAddress, requestTimeout: Duration, name: MetricAddress, pendingBufferSize: Int = 100, sentBufferSize: Int = 20, failFast: Boolean = false, connectionAttempts: PollingDuration = ..., idleTimeout: Duration = Duration.Inf) extends Product with Serializable

    Configuration used to specify a Client's parameters

    Configuration used to specify a Client's parameters

    address

    The address with which to connect

    requestTimeout

    The request timeout value

    name

    The MetricAddress associated with this client

    pendingBufferSize

    Size of the pending buffer

    sentBufferSize

    Size of the sent buffer

    failFast

    When a failure is detected, immediately fail all pending requests.

    connectionAttempts

    Polling configuration to govern retry behavior for both initial connect attempts and for connection lost events.

  12. sealed trait ClientConnectionEvent extends ConnectionEvent

  13. class ClientOverloadedException extends ServiceClientException

    Thrown when the pending buffer is full

  14. class ClientProxy extends Actor with ActorLogging with Stash

    This correctly routes messages to the right worker and handler

  15. trait Codec[Output, Input] extends AnyRef

    A Codec is a stateful object for converting requests/responses to/from DataBuffers.

    A Codec is a stateful object for converting requests/responses to/from DataBuffers. IMPORTANT - when decoding, a codec must be able to handle both partial responses and multiple responses in a single DataBuffer. This is why a codec is stateful and returns a Seq[O]

  16. trait CodecDSL extends AnyRef

  17. trait CodecProvider[C <: CodecDSL] extends AnyRef

    Provide a Codec as well as some convenience functions for usage within in a Service.

    Provide a Codec as well as some convenience functions for usage within in a Service.

    C

    the type of codec this provider will supply

  18. trait ConnectionContext[C <: CodecDSL] extends AnyRef

  19. sealed trait ConnectionEvent extends AnyRef

  20. class ConnectionLostException extends ServiceClientException

    Thrown when a request is lost in transit

  21. abstract class DSLDelegator[C <: CodecDSL] extends Delegator with ServiceContext[C]

  22. trait DSLHandler[C <: CodecDSL] extends ServiceServer[service.DSLHandler.C.Input, service.DSLHandler.C.Output] with ConnectionContext[C]

  23. class DataException extends ServiceClientException

    Thrown when there's some kind of data error

  24. sealed trait DecodedResult[+T] extends AnyRef

  25. trait DefaultHandler extends CodecDSL

  26. class DefaultTagDecorator[I, O] extends TagDecorator[I, O]

  27. class Delayer extends Actor with ActorLogging

    This little actor is needed because apparently actors that are running in a pinned dispatcher AND are sending messages to themselves (like workers) cannot use the scheduler...the messages never get sent.

    This little actor is needed because apparently actors that are running in a pinned dispatcher AND are sending messages to themselves (like workers) cannot use the scheduler...the messages never get sent. So we get around this by sending a message to this actor living in the default dispatcher which then does the proper scheduling

  28. class DroppedReply extends Error

  29. class LoadBalancingClient[I, O] extends ServiceClientLike[I, O] with WorkerItem

    The LoadBalancingClient will evenly distribute requests across a set of clients.

    The LoadBalancingClient will evenly distribute requests across a set of clients. If one client begins failing, the balancer will retry up to numRetries times across the other clients (with each failover hitting different clients to avoid a cascading pileup

    Note that the balancer will never try the same client twice for a request, so setting maxTries to a very large number will mean that every client will be tried once

  30. class LoadBalancingClientException extends Exception

  31. case class MappedCallback[I, O](trigger: ((Try[I]) ⇒ Unit) ⇒ Unit, handler: (Try[I]) ⇒ Try[O]) extends Callback[O] with Product with Serializable

  32. trait MessageDecoder[T] extends AnyRef

  33. trait MessageEncoder[T] extends AnyRef

  34. class NotConnectedException extends ServiceClientException

    Throw when a request is attempted while not connected

  35. class PermutationGenerator[T] extends Iterator[List[T]]

    The PermutationGenerator creates permutations such that consecutive calls are guaranteed to cycle though all items as the first element.

    The PermutationGenerator creates permutations such that consecutive calls are guaranteed to cycle though all items as the first element.

    This currently doesn't iterate through every possible permutation, but it does evenly distribute 1st and 2nd tries...needs some more work

  36. class ReceiveException extends Exception

  37. class RequestBufferFullException extends Exception

  38. class RequestTimeoutException extends ServiceClientException

    Returned when a request has been pending for too long

  39. class SendFailedException extends Exception

  40. class ServiceClient[I, O] extends Controller[O, I] with ClientConnectionHandler with ServiceClientLike[I, O] with ManualUnbindHandler

    A ServiceClient is a non-blocking, synchronous interface that handles sending atomic commands on a connection and parsing their replies

    A ServiceClient is a non-blocking, synchronous interface that handles sending atomic commands on a connection and parsing their replies

    Notice - The client will not begin to connect until it is bound to a worker, so when using the default constructor a service client will not connect on it's own. You must either call bind on the client or use the constructor that accepts a worker

  41. class ServiceClientException extends Exception

  42. trait ServiceClientLike[I, O] extends AnyRef

  43. class ServiceClientPool[I, O, T <: ServiceClient[I, O]] extends AnyRef

    A ClientPool is a simple container of open connections.

    A ClientPool is a simple container of open connections. It can receive updates and will open/close connections accordingly.

    note that config will be copied for each client, replacing only the address

  44. case class ServiceConfig(name: MetricAddress, requestTimeout: Duration, requestBufferSize: Int = 100, logErrors: Boolean = true) extends Product with Serializable

    Configuration class for a Service Server Connection Handler

    Configuration class for a Service Server Connection Handler

    name

    the prefix to use for all metrics generated by the service

    requestTimeout

    how long to wait until we timeout the request

    requestBufferSize

    how many concurrent requests a single connection can be processing

  45. trait ServiceContext[C <: CodecDSL] extends AnyRef

  46. abstract class ServiceServer[I, O] extends Controller[I, O]

    The ServiceServer provides an interface and basic functionality to create a server that processes requests and returns responses over a codec.

    The ServiceServer provides an interface and basic functionality to create a server that processes requests and returns responses over a codec.

    A Codec is simply the format in which the data is represented. Http, Redis protocol, Memcached protocl are all examples(and natively supported). It is entirely possible to use an additional Codec by creating a Codec to parse the desired protocol.

    Requests can be processed synchronously or asynchronously. The server will ensure that all responses are written back in the order that they are received.

  47. class StaleClientException extends Exception

    This is thrown when a Client is manually disconnected, and subsequent attempt is made to reconnect.

    This is thrown when a Client is manually disconnected, and subsequent attempt is made to reconnect. To simplify the internal workings of Clients, instead of trying to reset its internal state, it throws. Create a new Client to reestablish a connection.

  48. trait TagDecorator[I, O] extends AnyRef

  49. class UnhandledRequestException extends Exception

  50. case class UnmappedCallback[I](trigger: ((Try[I]) ⇒ Unit) ⇒ Unit) extends Callback[I] with Product with Serializable

    UnmappedCallback is essentially an optimization that avoids needing to create a MappedCallback with an identity function

Value Members

  1. object AsyncServiceClient

  2. object Callback

  3. object CallbackExecutor extends Serializable

  4. object Codec

  5. object CodecDSL

  6. object ConnectionEvent

  7. object DecodedResult

  8. object Service

    The Service object is an entry point into the the Service DSL which provide some convenience functions for quickly creating a Server serving responses to requests utilizing a Codec(ie: memcached, http, redis, etc).

    The Service object is an entry point into the the Service DSL which provide some convenience functions for quickly creating a Server serving responses to requests utilizing a Codec(ie: memcached, http, redis, etc).

    One thing to always keep in mind is that code inside the Service.serve is placed inside a Delegator and ConnectionHandler, which means that it directly runs inside of a Worker and its SelectLoop. Be VERY mindful of the code that you place in here, as if there is any blocking code it will block the Worker. Not good.

    An example with full typing in place to illustrate :

    import colossus.protocols.http._  //imports an implicit codec
    
    implicit val ioSystem : IOSystem = myBootStrappingFunction()
    
    Service.serve[Http]("my-app", 9090) { context : ServiceContext[Http] =>
    
      //everything in this block happens on delegator initialization, which is on application startup.  One time only.
    
      context.handle { connection : ConnectionContext[Http] => {
          //This block is for connectionHandler initialization. Happens in the event loop.  Don't block.
          //Note, that a connection can handle multiple requests.
          connection.become {
            //this partial function is what "handles" a request.  Again.. don't block.
            case req @ Get on Text("test") => future(req.ok(someService.getDataFromStore()))
            case req @ Get on Text("path") => req.ok("path")
          }
        }
      }
    }
  9. object ServiceServer

  10. object TagDecorator

Ungrouped