/* * Copyright 2007-2010 Sun Microsystems, Inc. * * This file is part of Project Darkstar Server. * * Project Darkstar Server is free software: you can redistribute it * and/or modify it under the terms of the GNU General Public License * version 2 as published by the Free Software Foundation and * distributed hereunder to you. * * Project Darkstar Server is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Sun designates this particular file as subject to the "Classpath" * exception as provided by Sun in the LICENSE file that accompanied * this code. * * -- */ package com.sun.sgs.kernel; import com.sun.sgs.app.TransactionAbortedException; import com.sun.sgs.app.TransactionNotActiveException; import com.sun.sgs.service.Transaction; /** * Used to report to the {@link AccessCoordinator} when access is * requested to a shared object. Methods must be called in the context * of an active transaction, or provide a transaction in which the * context of the request took place. The latter option is primarily * provided for services to report accesses that were only detected * during the prepare phase when the transaction is no longer active. * <p> * All methods of {@code AccessReporter} take an object identifier as a * parameter. This parameter must implement {@code equals()} and * {@code hashCode()}. To make the resulting detail provided to the * profiler as useful as possible, the identifier should have a meaningful * {@code toString()} method. Other than this the identifier may be any * arbitrary instance, including the requested object itself, as long as * it uniquely identifies the object across transactions. * <p> * For the {@code reportObjectAccess} methods, access should be * reported as early as possible. In particular, if actually resolving * or retrieving the object could fail, or incur any significant * expense, the report should be made first. This is to ensure that * access is always noted, and has the chance to abort the transaction * before any unneeded processing is done. For instance, in the case * of the {@code DataService}, before a name binding is resolved in * the {@code getBinding} method, the requested access to that bound * object should be reported. * <p> * If the implementation of the {@code reportObjectAccess} methods detect a * conflict and wish to cause the calling transaction to fail, they will abort * the transaction and then throw a {@link TransactionAbortedException}. * * @param <T> the type of the identifier used to identify accessed objects */ public interface AccessReporter<T> { /** The type of access requested. */ enum AccessType { /** The object is being accessed, but not modified. */ READ, /** The object is being modified. */ WRITE } /** * Reports to the coordinator that object access has been requested in * the context of the current transaction. The requested object is shared, * and may be the cause of conflict. * * @param objId an identifier for the object being accessed * @param type the {@code AccessType} being requested * * @throws TransactionNotActiveException if not called in the context * of an active transaction * @throws TransactionAbortedException if access failed due to a conflict */ void reportObjectAccess(T objId, AccessType type); /** * Reports to the coordinator that object access has been requested in * the context of the provided transaction. The requested object is * shared, and may be the cause of conflict. * * @param txn the transaction in which the provided {@code objId} * was accessed * @param objId an identifier for the object being accessed * @param type the {@code AccessType} being requested * * @throws IllegalArgumentException if the provided transaction is invalid, * has already committed, or is otherwise * unknown to the {@code AccessCoordinator} * @throws TransactionAbortedException if access failed due to a conflict */ void reportObjectAccess(Transaction txn, T objId, AccessType type); /** * Reports to the coordinator that an object access with the provided * description has been requested in the context of the current * transaction. The requested object is shared, and may be the cause * of conflict. See {@code setObjectDescription} for more details about * {@code description}. * * @param objId an identifier for the object being accessed * @param type the {@code AccessType} being requested * @param description an arbitrary object that contains a * description of the object being accessed * * @throws TransactionNotActiveException if not called in the context * of an active transaction * @throws TransactionAbortedException if access failed due to a conflict */ void reportObjectAccess(T objId, AccessType type, Object description); /** * Reports to the coordinator that an object access with the provided * description has been requested in the context of the provided * transaction. The requested object is shared, and may be the cause * of conflict. See {@code setObjectDescription} for more details about * {@code description}. * * @param txn the transaction in which the provided {@code objId} * was accessed * @param objId an identifier for the object being accessed * @param type the {@code AccessType} being requested * @param description an arbitrary object that contains a * description of the object being accessed * * @throws IllegalArgumentException if the provided transaction is invalid, * has already committed, or is otherwise * unknown to the {@code AccessCoordinator} * @throws TransactionAbortedException if access failed due to a conflict */ void reportObjectAccess(Transaction txn, T objId, AccessType type, Object description); /** * In the current transaction, associates the given object with * some description that should have a meaningful {@code toString} * method. This description will be available in the profiling data, * and is useful when displaying details about a given accessed * object. The intent is that an arbitrary description can be * included with an object, but that the description is not * accessed unless a {@code ProfileListener} finds it useful to do * so. At that point the description's {@code toString} method may * be called, or the object itself might be cast to some known type * to extract more detail about the accessed object. * <p> * Note that this may be called before the associated object is * actually accessed, and therefore before {@code reportObjectAccess} * is called for the given {@code objId}. Use of this method is * optional, and only used to provide additional detail for profiling * and debugging. * <p> * If a description has already been set for the identified object, * or if the provided description is {@code null}, then no change is * made to the description of the object. * * @param objId the identifier for the associated object * @param description an arbitrary {@code Object} that contains a * description of the objId being accessed * * @throws TransactionNotActiveException if not called in the context * of an active transaction */ void setObjectDescription(T objId, Object description); /** * In the provided transaction, associates the given object with * some description that should have a meaningful {@code toString} * method. This description will be available in the profiling data, * and is useful when displaying details about a given accessed * object. The intent is that an arbitrary description can be * included with an object, but that the description is not * accessed unless a {@code ProfileListener} finds it useful to do * so. At that point the description's {@code toString} method may * be called, or the object itself might be cast to some known type * to extract more detail about the accessed object. * <p> * Note that this may be called before the associated object is * actually accessed, and therefore before {@code reportObjectAccess} * is called for the given {@code objId}. Use of this method is * optional, and only used to provide additional detail for profiling * and debugging. * <p> * If a description has already been set for the identified object, * or if the provided description is {@code null}, then no change is * made to the description of the object. * * @param txn the transaction in which the provided {@code objId} * was accessed * @param objId the identifier for the associated object * @param description an arbitrary {@code Object} that contains a * description of the objId being accessed * * @throws IllegalArgumentException if the provided transaction is invalid, * has already committed, or is otherwise * unknown to the {@code AccessCoordinator} */ void setObjectDescription(Transaction txn, T objId, Object description); }