public class ClientAsynchronousIterator<E> extends Object implements IAsynchronousIterator<E>, Serializable
RemoteAsynchronousIterator
so that it looks like an
IAsynchronousIterator
again.
This implementation uses the caller's ExecutorService
to run a task
that migrates data from the remote IAsynchronousIterator
into a local
BlockingBuffer
. The client implementation uses purely local
operations to test the contents of the local BlockingBuffer
. This
means that operations like hasNext(long, TimeUnit)
may be used with
short timeouts without possibility of blocking IO.
Note: This class is NOT thread-safe. There should be only a single process draining the iterator.
Note: In order to conserve resources, the caller is advised to use
start(ExecutorService)
before making any other requests. This will
allow the caller to specify an ExecutorService
that will be tasked
with buffering elements from the RemoteAsynchronousIterator
. When
start(ExecutorService)
is not invoked explicitly, a new
Thread
will be allocated. Typically, an ExecutorService
can
be much more efficient than creating a new Thread
.
Modifier and Type | Field and Description |
---|---|
protected static boolean |
DEBUG |
protected static boolean |
INFO |
protected static org.apache.log4j.Logger |
log |
protected static long |
timeout
Timeout for the
ReaderTask when it invokes
RemoteAsynchronousIterator.hasNext(long, TimeUnit) . |
protected static boolean |
trace
Enables low-level trace of the
ReaderTask . |
protected static TimeUnit |
unit
The units for
timeout . |
Constructor and Description |
---|
ClientAsynchronousIterator(RemoteAsynchronousIterator<E> remoteIterator,
int capacity) |
Modifier and Type | Method and Description |
---|---|
void |
close()
Notes that the iterator is closed and hence may no longer be read.
|
boolean |
hasNext() |
boolean |
hasNext(long timeout,
TimeUnit unit)
Return
true iff there is at least one element that can be
visited. |
boolean |
isExhausted()
Return
true iff this iterator will not visit any more
elements (non-blocking). |
E |
next() |
E |
next(long timeout,
TimeUnit unit)
Waits up to the timeout to return the next element.
|
void |
remove()
Operation is not supported.
|
protected void |
start()
Start the
ReaderTask iff it is not already running. |
void |
start(ExecutorService executorService)
Start the
ReaderTask that will populate the local buffer with
elements from the remote iterator. |
protected static final transient org.apache.log4j.Logger log
protected static final transient boolean INFO
protected static final transient boolean DEBUG
protected static final transient long timeout
ReaderTask
when it invokes
RemoteAsynchronousIterator.hasNext(long, TimeUnit)
.
Note: A timeout is used instead of
RemoteAsynchronousIterator.hasNext()
in order to avoid blocking
during an RMI call on a remote thread.
protected static final transient boolean trace
ReaderTask
.public ClientAsynchronousIterator(RemoteAsynchronousIterator<E> remoteIterator, int capacity)
remoteIterator
- A proxy for the remote iterator from which the elements are
being read.capacity
- The capacity of the internal IBlockingBuffer
.public void start(ExecutorService executorService)
ReaderTask
that will populate the local buffer with
elements from the remote iterator.
When start(ExecutorService)
is not invoked explicitly, a new
Thread
will be allocated and the ReaderTask
will be run
on that Thread
. Typically, an ExecutorService
can be
much more efficient than creating a new Thread
. Therefore the
caller is encourged to break encapsulation and specify the
ExecutorService
on which the ReaderTask
will run
directly.
IllegalStateException
- if the ReaderTask
is already running.protected final void start()
ReaderTask
iff it is not already running.public void close()
IAsynchronousIterator
IBlockingBuffer
from
filling up and deadlocking. For this reason, IAsynchronousIterator.close()
has
consequences NOT entailed by ICloseableIterator
.
Note: Depending on the semantics of the producer, it MAY choose to treat
an interrupt() as normal (but eager) termination. For example, rule
execution treats an interrupt() as normal (but eager) termination with
the consequence that queries may be safely interrupted once some limit
has been satisfied. However, the preferred way to treat LIMIT is using
IRule
with an IQueryOptions
that specifies a LIMIT.
close
in interface IAsynchronousIterator<E>
close
in interface ICloseable
close
in interface ICloseableIterator<E>
public boolean hasNext(long timeout, TimeUnit unit) throws InterruptedException
IAsynchronousIterator
true
iff there is at least one element that can be
visited. If the buffer is empty then this will block until: (a) an
element appears in the buffer; (b) the buffer is
BlockingBuffer.close()
ed; or (c) the timeout expires.
Note that a false
return DOES NOT signify that the iterator
is exhausted. However, if you specify an infinite timeout using
Long.MAX_VALUE
TimeUnit.SECONDS
then you MAY safely
interpret a false
return as an indication that the iterator
is exhausted.
hasNext
in interface IAsynchronousIterator<E>
timeout
- The length of time that the method may block awaiting an
element to appear.unit
- The units in which the timeout is expressed.true
iff there is an element available.InterruptedException
- if the current thread is interrupted while waiting another
element.public boolean isExhausted()
IAsynchronousIterator
true
iff this iterator will not visit any more
elements (non-blocking).isExhausted
in interface IAsynchronousIterator<E>
true
iff the iterator is known to be exhausted
without blocking. A false
return does NOT imply
that the iterator will visit more elements, only that it MIGHT
visit more elements.public E next(long timeout, TimeUnit unit) throws InterruptedException
IAsynchronousIterator
next
in interface IAsynchronousIterator<E>
timeout
- The timeout (overrides the chunkTimeout specified to
the BlockingBuffer
ctor).unit
- The unit in which the timeout is expressed.null
iff the timeout was exceeded
before IAsynchronousIterator.hasNext(long, TimeUnit)
returned
true
.
In order to have a definitive indication that the iterator is
exhausted you need to invoke Iterator.hasNext()
without a timeout
(blocking) or IAsynchronousIterator.isExhausted()
(non-blocking).
InterruptedException
- if the current thread is interrupted while waiting for
another element.public void remove()
remove
in interface Iterator<E>
UnsupportedOperationException
- always.Copyright © 2006–2019 SYSTAP, LLC DBA Blazegraph. All rights reserved.