com.yahoo.jdisc.handler.RequestHandler Maven / Gradle / Ivy
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.jdisc.handler;
import com.yahoo.jdisc.Container;
import com.yahoo.jdisc.Request;
import com.yahoo.jdisc.Response;
import com.yahoo.jdisc.SharedResource;
import com.yahoo.jdisc.application.BindingRepository;
import com.yahoo.jdisc.application.ContainerActivator;
import com.yahoo.jdisc.application.ContainerBuilder;
import com.yahoo.jdisc.application.UriPattern;
import java.util.concurrent.TimeUnit;
/**
* This interface defines a component that is capable of acting as a handler for a {@link Request}. To activate a
* RequestHandler it must be {@link BindingRepository#bind(String, Object) bound} to a {@link UriPattern} within a
* {@link ContainerBuilder}, and that builder must be {@link ContainerActivator#activateContainer(ContainerBuilder)
* activated}.
*
* @author Simon Thoresen Hult
*/
public interface RequestHandler extends SharedResource {
/**
* This method will process the given {@link Request} and return a {@link ContentChannel} into which the caller
* can write the Request's content. For every call to this method, the implementation must call the provided {@link
* ResponseHandler} exactly once.
*
* Notice that unless this method throws an Exception, a reference to the currently active {@link Container}
* instance is kept internally until {@link ResponseHandler#handleResponse(Response)} has been called. This ensures
* that the configured environment of the Request is stable throughout its lifetime. Failure to call back with a
* Response will prevent the release of that reference, and therefore prevent the corresponding Container from ever
* shutting down. The requirement to call {@link ResponseHandler#handleResponse(Response)} is regardless of any
* subsequent errors that may occur while working with the returned ContentChannel.
*
* @param request The Request to handle.
* @param handler The handler to pass the corresponding {@link Response} to.
* @return The ContentChannel to write the Request content to. Notice that the ContentChannel itself also holds a
* Container reference, so failure to close this will prevent the Container from ever shutting down.
*/
ContentChannel handleRequest(Request request, ResponseHandler handler);
/**
* This method is called by the {@link Container} when a {@link Request} that was previously accepted by {@link
* #handleRequest(Request, ResponseHandler)} has timed out. If the Request has no timeout (i.e. {@link
* Request#getTimeout(TimeUnit)} returns null), then this method is never called.
*
* The given {@link ResponseHandler} is the same ResponseHandler that was initially passed to the {@link
* #handleRequest(Request, ResponseHandler)} method, and it is guarded by a volatile boolean so that only the first
* call to {@link ResponseHandler#handleResponse(Response)} is actually passed on. This means that you do NOT need
* to manage the ResponseHandlers yourself to prevent a late Response from calling the same ResponseHandler.
*
* Notice that you MUST call {@link ResponseHandler#handleResponse(Response)} as a reaction to having this method
* invoked. Failure to do so will prevent the Container from ever shutting down.
*
* @param request The Request that has timed out.
* @param handler The handler to pass the timeout {@link Response} to.
* @see Response#dispatchTimeout(ResponseHandler)
*/
void handleTimeout(Request request, ResponseHandler handler);
}