// Copyright Vespa.ai. 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); }