@PublicApi
Package com.yahoo.jdisc.handler
Provides classes and interfaces for implementing a RequestHandler
.
RequestHandler
All Requests
in a jDISC application are processed by RequestHandlers. These are
components created by the Application
, and bound to one or more URI
patterns through the ContainerBuilder
API. Upon receiving a
Request, a RequestHandler must return a ContentChannel
into which the
caller can asynchronously write the Request's payload. The ContentChannel is an asynchronous API for ByteBuffer
hand-over, with support for asynchronous completion-notification (through the CompletionHandler
interface). Once the Request has been processed (which
may or may not involve dispatching one or more child-Requests), the RequestHandler must prepare a Response
object and asynchronously pass that to the corresponding ResponseHandler
. One of the most vital parts of the RequestHandler definition
is that it must provide exactly one Response for every Request. This guarantee simplifies the usage pattern of
RequestHandlers, and allows other components to skip a lot of bookkeeping. If a RequestHandler decides to create and
dispatch a child-Request, it is done through the same BindingSet
mechanics that was used to resolve the current RequestHandler. Because all ServerProviders
use "localhost" for Request URI hostname, most RequestHandlers
are also bound to "localhost". Those that are not typically provide a specific service for one or more remote hosts
(these are ClientProviders
).
@Inject MyApplication(ContainerActivator activator, CurrentContainer container) { ContainerBuilder builder = activator.newContainerBuilder(); builder.serverBindings().bind("http://localhost/*", new MyRequestHandler()); activator.activateContainer(builder); }
Because the entirety of the RequestHandler stack (RequestHandler, ResponseHandler, ContentChannel and
CompletionHandler) is asynchronous, an active Container
can handle as many
concurrent Requests as the sum capacity of all installed ServerProviders. Furthermore, the APIs have been designed in
such a way that the ContentChannel returned back to the initial call to a RequestHandler can be the very same
ContentChannel as is returned by the final destination of a Request. This means that, unless explicitly implemented
otherwise, a jDISC application that is intended to forward large streams of data can do so without having to make any
copies of that data as it is passing through.
ResponseHandler
The complement of the Request is the Response. A Response is a numeric status code and a set of header fields. Just as Requests are processed by RequestHandlers, Responses are processed by ResponseHandlers. The ResponseHandler interface is fully asynchronous, and uses the ContentChannel class to encapsulate the asynchronous passing of Response content. Where the RequestHandler is part of the Container and it's BindingSets, the ResponseHandler is part of the Request context. With every call to a RequestHandler you must also provide a ResponseHandler. Because the Request itself is not part of the ResponseHandler API, there is no built-in feature to tell a ResponseHandler which Request the Response corresponds to. Instead, one should create per-Request light-weight ResponseHandler objects that encapsulate the necessary context for Response processing. This was a deliberate design choice based on observed usage patterns of a different but similar architecture (the messaging layer of the Vespa platform).
A Request may or may not have an assigned timeout. Both a ServerProvider and a RequestHandler may choose to assign
a timeout to a Request, but only the first to assign it has an effect. The timeout is the maximum allowed time for a
RequestHandler to wait before calling the ResponseHandler. There is no monitoring of the associated ContentChannels
of either Request or Response, so once a Response has been dispatched a ContentChannel can stay open indefinetly.
Timeouts are managed by a jDISC core component, but a RequestHandler may ask a Request at any time whether or not it
has timed out. This allows RequestHandlers to terminate CPU-intensive processing of Requests whose Response will be
discarded anyway. Once timeout occurs, the timeout manager calls the appropriate RequestHandler.handleTimeout(Request, ResponseHandler)
method. All future calls to that
ResponseHandler is blocked, as to uphold the guarantee that a Request should have exactly one Response.
- See Also:
com.yahoo.jdisc
,com.yahoo.jdisc.application
,com.yahoo.jdisc.service
-
Interface Summary Interface Description CompletionHandler This interface defines a handler for consuming the result of an asynchronous I/O operation.ContentChannel RequestHandler This interface defines a component that is capable of acting as a handler for aRequest
.ResponseHandler This interface defines a component that is capable of acting as a handler for aResponse
. -
Class Summary Class Description AbstractRequestHandler This class provides an abstractRequestHandler
implementation with reasonable defaults for everything butRequestHandler.handleRequest(Request, ResponseHandler)
.BlockingContentWriter This class provides a blocking write-interface to aContentChannel
.BufferedContentChannel This class implements an unlimited, non-blocking content queue.CallableRequestDispatch This is a convenient subclass ofRequestDispatch
that implements theCallable
interface.CallableResponseDispatch This is a convenient subclass ofResponseDispatch
that implements theCallable
interface.ContentInputStream This class extendsUnsafeContentInputStream
and adds a finalizer to it that callsUnsafeContentInputStream.close()
.FastContentOutputStream This class extends theAbstractContentOutputStream
, and forwards all write() and close() calls to aFastContentWriter
.FastContentWriter This class provides a non-blocking, awaitable write-interface to aContentChannel
.FutureCompletion This class provides an implementation ofCompletionHandler
that allows you to wait for eitherFutureCompletion.completed()
orFutureCompletion.failed(Throwable)
to be called.FutureConjunction This class implements a Future<Boolean> that is conjunction of zero or more other Future<Boolean>s, i.e.FutureResponse This class provides an implementation ofResponseHandler
that allows you to wait for aResponse
to be returned.NullContent This class provides a convenient implementation ofContentChannel
that does not support being written to.ReadableContentChannel This class implements aContentChannel
that has a blocking read interface.RequestDispatch This class provides a convenient way of safely dispatching aRequest
.ResponseDispatch This class provides a convenient way of safely dispatching aResponse
.ThreadedRequestHandler This class implements aRequestHandler
with a synchronousThreadedRequestHandler.handleRequest(Request, BufferedContentChannel, ResponseHandler)
API for handlingRequest
s.UnsafeContentInputStream This class provides an adapter from aReadableContentChannel
to an InputStream. -
Exception Summary Exception Description BindingNotFoundException This exception is used to signal that no binding was found for theURI
of a givenRequest
.OverloadException An exception to signal abort current action, as the container is overloaded.RequestDeniedException This exception is used to signal that aRequest
was rejected by the correspondingClientProvider
orRequestHandler
.