001: /*
002: * Copyright (c) 2001 by Matt Welsh and The Regents of the University of
003: * California. All rights reserved.
004: *
005: * Permission to use, copy, modify, and distribute this software and its
006: * documentation for any purpose, without fee, and without written agreement is
007: * hereby granted, provided that the above copyright notice and the following
008: * two paragraphs appear in all copies of this software.
009: *
010: * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
011: * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
012: * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
013: * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
014: *
015: * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
016: * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
017: * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
018: * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
019: * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
020: *
021: * Author: Matt Welsh <mdw@cs.berkeley.edu>
022: *
023: */
024:
025: package seda.sandStorm.api;
026:
027: /**
028: * A SinkIF implements the 'sink' end of a finite-length event queue:
029: * it supports enqueue operations only. These operations can throw a
030: * SinkException if the sink is closed or becomes full, allowing event
031: * queues to support thresholding and backpressure.
032: *
033: * @author Matt Welsh
034: */
035: public interface SinkIF {
036:
037: /**
038: * Enqueues the given element onto the queue.
039: *
040: * @param element The <code>QueueElementIF</code> to enqueue
041: * @exception SinkFullException Indicates that the sink is temporarily full.
042: * @exception SinkClosedException Indicates that the sink is
043: * no longer being serviced.
044: */
045: public void enqueue(QueueElementIF element) throws SinkException;
046:
047: /**
048: * Enqueues the given element onto the queue.
049: *
050: * This is lossy in that this method drops the element if the element
051: * could not be enqueued, rather than throwing a SinkFullException or
052: * SinkClosedException. This is meant as a convenience interface for
053: * "low priority" enqueue events which can be safely dropped.
054: *
055: * @param element The <code>QueueElementIF</code> to enqueue
056: * @return true if the element was enqueued, false otherwise.
057: *
058: */
059: public boolean enqueue_lossy(QueueElementIF element);
060:
061: /**
062: * Given an array of elements, atomically enqueues all of the elements
063: * in the array. This guarantees that no other thread can interleave its
064: * own elements with those being inserted from this array. The
065: * implementation must enqueue all of the elements or none of them;
066: * if a SinkFullException or SinkClosedException is thrown, none of
067: * the elements will have been enqueued. This implies that the enqueue
068: * predicate (if any) must accept all elements in the array for the
069: * enqueue to proceed.
070: *
071: * @param elements The element array to enqueue
072: * @exception SinkFullException Indicates that the sink is temporarily full.
073: * @exception SinkClosedException Indicates that the sink is
074: * no longer being serviced.
075: *
076: */
077: public void enqueue_many(QueueElementIF[] elements)
078: throws SinkException;
079:
080: /**
081: * Support for transactional enqueue.
082: *
083: * <p>This method allows a client to provisionally enqueue a number
084: * of elements onto the queue, and then later commit the enqueue (with
085: * a <tt>enqueue_commit()</tt> call), or abort (with a
086: * <tt>enqueue_abort()</tt> call). This mechanism can be used to
087: * perform "split-phase" enqueues, where a client first enqueues a
088: * set of elements on the queue and then performs some work to "fill in"
089: * those elements before performing a commit. This can also be used
090: * to perform multi-queue transactional enqueue operations, with an
091: * "all-or-nothing" strategy for enqueueing events on multiple queues.
092: *
093: * <p>This method would generally be used in the following manner:
094: * <pre>
095: * Object key = sink.enqueue_prepare(someElements);
096: * if (can_commit) {
097: * sink.enqueue_commit(key);
098: * } else {
099: * sink.enqueue_abort(key);
100: * }
101: * </pre>
102: *
103: * <p> Note that this method does <b>not</b> protect against
104: * "dangling prepares" -- that is, a prepare without an associated
105: * commit or abort operation. This method should be used with care.
106: * In particular, be sure that all code paths (such as exceptions)
107: * after a prepare include either a commit or an abort.
108: *
109: * <p>Like <tt>enqueue_many</tt>, <tt>enqueue_prepare</tt> is an
110: * "all or none" operation: the enqueue predicate must accept all
111: * elements for enqueue, or none of them will be enqueued.
112: *
113: * @param elements The element array to provisionally enqueue
114: * @return A "transaction key" that may be used to commit or abort
115: * the provisional enqueue
116: * @exception SinkFullException Indicates that the sink is temporarily full
117: * and that the requested elements could not be provisionally enqueued.
118: * @exception SinkClosedException Indicates that the sink is
119: * no longer being serviced.
120: *
121: * @see enqueue_commit
122: * @see enqueue_abort
123: */
124: public Object enqueue_prepare(QueueElementIF[] elements)
125: throws SinkException;
126:
127: /**
128: * Commit a previously prepared provisional enqueue operation (from
129: * the <tt>enqueue_prepare()</tt> method). Causes the provisionally
130: * enqueued elements to appear on the queue for future dequeue operations.
131: * Note that once a <tt>enqueue_prepare()</tt> has returned an enqueue
132: * key, the queue cannot reject the entries.
133: *
134: * @param key The enqueue key returned by a previous call to
135: * <tt>enqueue_prepare()</tt>.
136: * @exception IllegalArgumentException Thrown if an unknown enqueue key
137: * is provided.
138: */
139: public void enqueue_commit(Object enqueue_key);
140:
141: /**
142: * Abort a previously prepared provisional enqueue operation (from
143: * the <tt>enqueue_prepare()</tt> method). Causes the queue to discard
144: * the provisionally enqueued elements.
145: *
146: * @param key The enqueue key returned by a previous call to
147: * <tt>enqueue_prepare()</tt>.
148: * @exception IllegalArgumentException Thrown if an unknown enqueue key
149: * is provided.
150: */
151: public void enqueue_abort(Object enqueue_key);
152:
153: /**
154: * Set the enqueue predicate for this sink. This mechanism allows
155: * user to define a method that will 'screen' QueueElementIF's during
156: * the enqueue procedure to either accept or reject them. The enqueue
157: * predicate runs in the context of the <b>caller of enqueue()</b>,
158: * which means it must be simple and fast. This can be used to implement
159: * many interesting queue-thresholding policies, such as simple count
160: * threshold, credit-based mechanisms, and more.
161: */
162: public void setEnqueuePredicate(EnqueuePredicateIF pred);
163:
164: /**
165: * Return the enqueue predicate for this sink.
166: */
167: public EnqueuePredicateIF getEnqueuePredicate();
168:
169: /**
170: * Return the number of elements in this sink.
171: */
172: public int size();
173:
174: }
|