@PublicApi
RequestHandler
.See: Description
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 a
Request . |
ResponseHandler |
This interface defines a component that is capable of acting as a handler for a
Response . |
Class | Description |
---|---|
AbstractContentOutputStream | |
AbstractRequestHandler |
This class provides an abstract
RequestHandler implementation with reasonable defaults for everything but
RequestHandler.handleRequest(Request, ResponseHandler) . |
BlockingContentWriter |
This class provides a blocking write-interface to a
ContentChannel . |
BufferedContentChannel |
This class implements an unlimited, non-blocking content queue.
|
BufferedContentChannel.Entry | |
CallableRequestDispatch |
This is a convenient subclass of
RequestDispatch that implements the Callable interface. |
CallableResponseDispatch |
This is a convenient subclass of
ResponseDispatch that implements the Callable interface. |
ContentInputStream |
This class extends
UnsafeContentInputStream and adds a finalizer to it that calls UnsafeContentInputStream.close() . |
FastContentOutputStream |
This class extends the
AbstractContentOutputStream , and forwards all write() and close() calls to a FastContentWriter . |
FastContentWriter |
This class provides a non-blocking, awaitable write-interface to a
ContentChannel . |
FutureCompletion |
This class provides an implementation of
CompletionHandler that allows you to wait for either FutureCompletion.completed() or FutureCompletion.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 of
ResponseHandler that allows you to wait for a Response to
be returned. |
NullContent |
This class provides a convenient implementation of
ContentChannel that does not support being written to. |
ReadableContentChannel |
This class implements a
ContentChannel that has a blocking read interface. |
ReadableContentChannel.Entry | |
RequestDispatch |
This class provides a convenient way of safely dispatching a
Request . |
ResponseDispatch |
This class provides a convenient way of safely dispatching a
Response . |
ThreadedRequestHandler |
This class implements a
RequestHandler with a synchronous ThreadedRequestHandler.handleRequest(Request,
BufferedContentChannel, ResponseHandler) API for handling Request s. |
UnsafeContentInputStream |
This class provides an adapter from a
ReadableContentChannel to an InputStream. |
Exception | Description |
---|---|
BindingNotFoundException | |
OverloadException |
An exception to signal abort current action, as the container is overloaded.
|
RequestDeniedException |
This exception is used to signal that a
Request was rejected by the corresponding ClientProvider
or RequestHandler . |
Provides classes and interfaces for implementing a 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.
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.
com.yahoo.jdisc
,
com.yahoo.jdisc.application
,
com.yahoo.jdisc.service
Copyright © 2018. All rights reserved.