oracle.kv.impl.async.DialogHandler Maven / Gradle / Ivy
Show all versions of oracle-nosql-server Show documentation
/*-
* Copyright (C) 2011, 2018 Oracle and/or its affiliates. All rights reserved.
*
* This file was distributed by Oracle as part of a version of Oracle NoSQL
* Database made available at:
*
* http://www.oracle.com/technetwork/database/database-technologies/nosqldb/downloads/index.html
*
* Please see the LICENSE file included in the top-level directory of the
* appropriate version of Oracle NoSQL Database for a copy of the license and
* additional information.
*/
package oracle.kv.impl.async;
import oracle.kv.RequestTimeoutException;
import oracle.kv.impl.async.exception.DialogException;
import oracle.kv.impl.async.exception.DialogBackoffException;
import oracle.kv.impl.async.exception.DialogNoBackoffException;
import oracle.kv.impl.async.exception.DialogUnknownException;
/**
* Handles the events of a dialog.
*
* Upper layers implement the following methods for a handler:
*
* - {@code onStart}
* called once as the first method of the handler;
* - {@code onCanWrite}
* called once, for a successful {@link DialogContext#write} with message
* M, when (1) M has been entirely written to the network buffer;
* and (2) at least one {@code DialogContext#write} failed due to M.
* - {@code onCanRead}
* called once each time when a new input message arrived for the handler;
* - {@code onAbort}
* called when the dialog is aborted.
*
*
* Each of the handler methods has a parameter {@code context} which is the
* {@link DialogContext} object associated with the handler. Handlers can
* manage message reads and writes by calling {@link DialogContext#read} and
* {@link DialogContext#write}.
*
*
All methods for an handler of an individual dialog will be called
* sequentially; only one method will be called at a time and the next method
* will not be called until the previous method exits.
*
*
Implementations of all methods on this interface should complete in a
* timely manner to avoid keeping the invoking thread from dispatching to other
* handlers.
*
*
There are two ways in which a dialog is considered finished with respect
* to this handler:
*
* - The dialog finished normally,
* in which case all of the following conditions occurred: (1) the {@code
* onCanRead} method was called with parameter {@code finished} set to {@code
* true}, which indicates the remote had finished writing messages, (2) the
* {@link DialogContext#read} method returns {@code null} after (1) occured,
* which indicates all incoming messages are retrieved, and (3) The {@code
* DialogContext#write} had been called successfully with parameter {@code
* finished} set to {@code true}, which indicates the dialog had finished
* writing messages from this side.
* - The dialog finished abruptly,
* in which case the {@code onAbort} method was called with the parameter {@code
* cause}.
*
*
* After a dialog is finished with respect to the handler (either normally
* or abruptly), no method of this interface will be called.
*/
public interface DialogHandler {
/**
* Called once when the handler starts.
*
* The method will be called as the first method for the handler even if it
* is already aborted.
*
* @param context the dialog context
* @param aborted {@code true} if dialog is already aborted
*/
void onStart(DialogContext context, boolean aborted);
/**
* Called to notify that a previously failed {@link DialogContext#write}
* may succeed.
*
*
A {@code DialogContext#write} can fail and return {@code false} if
* there is already a message M (written by a previous successful
* write) pending to send to the network buffer. In that case, when
* M has been entirely written to the network buffer, this method
* will be called once. The upper layer can attempt to write again when or
* after this method is called.
*
* @param context the dialog context
*/
void onCanWrite(DialogContext context);
/**
* Called once each time when a new {@link MessageInput} arrived for the
* handler.
*
*
{@link DialogContext#read} can be called to retrieve arrived
* messages.
*
*
Note that the following case may occur: a new message arrives, but
* before {@code onCanRead} is called, {@code DialogContext#read} gets
* called multiple times and retrieved all input messages including the
* newly arrived one. This result in a situation that a {@code
* DialogContext#read} call after a {@code onCanRead} call can return
* {@code null}.
*
* @param context the dialog context
* @param finished {@code true} if this is the last onCanRead call and no
* more input message will arrive
*/
void onCanRead(DialogContext context, boolean finished);
/**
* Called when the dialog is aborted.
*
*
The handler will not be able to read or write any more message after
* entering this method, i.e., calling {@link DialogContext#read} will
* return {@code null} and calling {@link DialogContext#write} will return
* {@code false}.
*
*
After this method is called, no subsequent method of this handler
* will be called.
*
*
The {@code cause} of the abort is either a {@link
* RequestTimeoutException} or a {@link DialogException}.
*
*
{@link RequestTimeoutException} is thrown when the dialog is not
* finished normally before the configured timeout interval. The dialog may
* have side effects on the remote.
*
*
{@link DialogException} is thrown for errors other than dialog
* timeout. The exception captures whether the exception is reported from
* remote ({@link DialogException#fromRemote}) and whether the dialog has
* some side effects on the remote ({@link DialogException#hasSideEffect}).
* The exception should be an instance of one of the three sub classes:
*
* - {@link DialogBackoffException}
*
- which is thrown when the causing problem is more persistent, e.g.,
* unknown host error, etc. The problem is not expected to disappear
* without more involved intervention and therefore the caller should
* backoff and not retry immediately.
*
- {@link DialogNoBackoffException}
*
- which is thrown when the causing problem is likely a temporary
* error, e.g., connection is timed out, etc. The caller could retry the
* dialog upont this exception.
*
- {@link DialogUnknownException}
*
- which is thrown when an unexpected error occurs. This usually means
* bugs in the code.
*
*
* @param context the dialog context
* @param cause cause of the abort
*/
void onAbort(DialogContext context, Throwable cause);
}