S - the type of the IoSession this processor can handlepublic abstract class AbstractPollingIoProcessor<S extends AbstractIoSession> extends java.lang.Object implements IoProcessor<S>
IoProcessor which helps transport
developers to write an IoProcessor easily. This class is in charge of
active polling a set of IoSession and trigger events when some I/O
operation is possible.| Modifier and Type | Class and Description |
|---|---|
private class |
AbstractPollingIoProcessor.Processor
The main loop.
|
| Modifier and Type | Field and Description |
|---|---|
private DefaultIoFuture |
disposalFuture |
private java.lang.Object |
disposalLock |
private boolean |
disposed |
private boolean |
disposing |
private java.util.concurrent.Executor |
executor
The executor to use when we need to start the inner Processor
|
private java.util.Queue<S> |
flushingSessions
A queue used to store the sessions to be flushed
|
private long |
lastIdleCheckTime |
private static org.slf4j.Logger |
LOG
A logger for this class
|
private java.util.Queue<S> |
newSessions
A Session queue containing the newly created sessions
|
private java.util.concurrent.atomic.AtomicReference<AbstractPollingIoProcessor.Processor> |
processorRef
The processor thread : it handles the incoming messages
|
private java.util.Queue<S> |
removingSessions
A queue used to store the sessions to be removed
|
private static long |
SELECT_TIMEOUT
A timeout used for the select, as we need to get out to deal with idle
sessions
|
private static java.util.concurrent.ConcurrentHashMap<java.lang.Class<?>,java.util.concurrent.atomic.AtomicInteger> |
threadIds
A map containing the last Thread ID for each class
|
private java.lang.String |
threadName
This IoProcessor instance name
|
private java.util.Queue<S> |
trafficControllingSessions
A queue used to store the sessions which have a trafficControl to be
updated
|
protected java.util.concurrent.atomic.AtomicBoolean |
wakeupCalled |
private static int |
WRITE_SPIN_COUNT
The maximum loop count for a write operation until
write(AbstractIoSession, IoBuffer, int) returns non-zero value. |
| Modifier | Constructor and Description |
|---|---|
protected |
AbstractPollingIoProcessor(java.util.concurrent.Executor executor)
Create an
AbstractPollingIoProcessor with the given
Executor for handling I/Os events. |
| Modifier and Type | Method and Description |
|---|---|
void |
add(S session)
Adds the specified
session to the I/O processor so that
the I/O processor starts to perform any I/O operations related
with the session. |
private boolean |
addNow(S session)
Process a new session :
- initialize it
- create its chain
- fire the CREATED listeners if any
|
protected abstract java.util.Iterator<S> |
allSessions()
|
private void |
clearWriteRequestQueue(S session) |
protected abstract void |
destroy(S session)
Destroy the underlying client socket handle
|
void |
dispose()
Releases any resources allocated by this processor.
|
protected abstract void |
doDispose()
Dispose the resources used by this
IoProcessor for polling the
client connections. |
private void |
fireMessageSent(S session,
WriteRequest req) |
private void |
flush(long currentTime)
Write all the pending messages
|
void |
flush(S session)
Flushes the internal write request queue of the specified
session. |
private boolean |
flushNow(S session,
long currentTime) |
protected abstract SessionState |
getState(S session)
Get the state of a session (preparing, open, closed)
|
private int |
handleNewSessions()
Loops over the new sessions blocking queue and returns the number of
sessions which are effectively created
|
protected abstract void |
init(S session)
Initialize the polling of a session.
|
protected abstract boolean |
isBrokenConnection()
Check that the select() has not exited immediately just because of a
broken connection.
|
boolean |
isDisposed()
Returns true if and if only all resources of this processor
have been disposed.
|
boolean |
isDisposing()
Returns true if and if only
IoProcessor.dispose() method has
been called. |
protected abstract boolean |
isInterestedInRead(S session)
is this session registered for reading
|
protected abstract boolean |
isInterestedInWrite(S session)
is this session registered for writing
|
protected abstract boolean |
isReadable(S session)
Is the session ready for reading
|
protected abstract boolean |
isSelectorEmpty()
Say if the list of
IoSession polled by this IoProcessor
is empty |
protected abstract boolean |
isWritable(S session)
Is the session ready for writing
|
private java.lang.String |
nextThreadName()
Compute the thread ID for this class instance.
|
private void |
notifyIdleSessions(long currentTime) |
private void |
process() |
private void |
process(S session)
Deal with session ready for the read or write operations, or both.
|
private void |
read(S session) |
protected abstract int |
read(S session,
IoBuffer buf)
|
protected abstract void |
registerNewSelector()
In the case we are using the java select() method, this method is used to
trash the buggy selector and create a new one, registring all the sockets
on it.
|
void |
remove(S session)
Removes and closes the specified
session from the I/O
processor so that the I/O processor closes the connection
associated with the session and releases any other related
resources. |
private boolean |
removeNow(S session) |
private int |
removeSessions() |
private void |
scheduleFlush(S session) |
private void |
scheduleRemove(S session) |
protected abstract int |
select()
poll those sessions forever
|
protected abstract int |
select(long timeout)
poll those sessions for the given timeout
|
protected abstract java.util.Iterator<S> |
selectedSessions()
|
protected abstract void |
setInterestedInRead(S session,
boolean isInterested)
register a session for reading
|
protected abstract void |
setInterestedInWrite(S session,
boolean isInterested)
register a session for writing
|
private void |
startupProcessor()
Starts the inner Processor, asking the executor to pick a thread in its
pool.
|
protected abstract int |
transferFile(S session,
FileRegion region,
int length)
Write a part of a file to a
IoSession, if the underlying API
isn't supporting system calls like sendfile(), you can throw a
UnsupportedOperationException so the file will be send using
usual write(AbstractIoSession, IoBuffer, int) call. |
void |
updateTrafficControl(S session)
Controls the traffic of the specified
session depending of the
IoSession.isReadSuspended() and IoSession.isWriteSuspended()
flags |
private void |
updateTrafficMask()
Update the trafficControl for all the session.
|
void |
updateTrafficMask(S session)
Updates the traffic mask for a given session
|
protected abstract void |
wakeup()
Interrupt the
select(long) call. |
protected abstract int |
write(S session,
IoBuffer buf,
int length)
Write a sequence of bytes to a
IoSession, means to be called when
a session was found ready for writing. |
void |
write(S session,
WriteRequest writeRequest)
Writes the WriteRequest for the specified
session. |
private int |
writeBuffer(S session,
WriteRequest req,
boolean hasFragmentation,
int maxLength,
long currentTime) |
private int |
writeFile(S session,
WriteRequest req,
boolean hasFragmentation,
int maxLength,
long currentTime) |
private static final org.slf4j.Logger LOG
private static final int WRITE_SPIN_COUNT
write(AbstractIoSession, IoBuffer, int) returns non-zero value.
It is similar to what a spin lock is for in concurrency programming. It
improves memory utilization and write throughput significantly.private static final long SELECT_TIMEOUT
private static final java.util.concurrent.ConcurrentHashMap<java.lang.Class<?>,java.util.concurrent.atomic.AtomicInteger> threadIds
private final java.lang.String threadName
private final java.util.concurrent.Executor executor
private final java.util.Queue<S extends AbstractIoSession> newSessions
private final java.util.Queue<S extends AbstractIoSession> removingSessions
private final java.util.Queue<S extends AbstractIoSession> flushingSessions
private final java.util.Queue<S extends AbstractIoSession> trafficControllingSessions
private final java.util.concurrent.atomic.AtomicReference<AbstractPollingIoProcessor.Processor> processorRef
private long lastIdleCheckTime
private final java.lang.Object disposalLock
private volatile boolean disposing
private volatile boolean disposed
private final DefaultIoFuture disposalFuture
protected java.util.concurrent.atomic.AtomicBoolean wakeupCalled
protected AbstractPollingIoProcessor(java.util.concurrent.Executor executor)
AbstractPollingIoProcessor with the given
Executor for handling I/Os events.executor - the Executor for handling I/O eventsprivate java.lang.String nextThreadName()
public final boolean isDisposing()
IoProcessor.dispose() method has
been called. Please note that this method will return true
even after all the related resources are released.isDisposing in interface IoProcessor<S extends AbstractIoSession>public final boolean isDisposed()
isDisposed in interface IoProcessor<S extends AbstractIoSession>public final void dispose()
dispose in interface IoProcessor<S extends AbstractIoSession>protected abstract void doDispose()
throws java.lang.Exception
IoProcessor for polling the
client connections. The implementing class doDispose method will be called.java.lang.Exception - if some low level IO error occursprotected abstract int select(long timeout)
throws java.lang.Exception
timeout - milliseconds before the call timeout if no event appearjava.lang.Exception - if some low level IO error occursprotected abstract int select()
throws java.lang.Exception
java.lang.Exception - if some low level IO error occursprotected abstract boolean isSelectorEmpty()
IoSession polled by this IoProcessor
is emptyIoProcessorprotected abstract void wakeup()
select(long) call.protected abstract java.util.Iterator<S> selectedSessions()
Iterator of IoSession read for I/Os operationprotected abstract SessionState getState(S session)
session - the IoSession to inspectprotected abstract boolean isWritable(S session)
session - the session queriedprotected abstract boolean isReadable(S session)
session - the session queriedprotected abstract void setInterestedInWrite(S session, boolean isInterested) throws java.lang.Exception
session - the session registeredisInterested - true for registering, false for removingjava.lang.Exceptionprotected abstract void setInterestedInRead(S session, boolean isInterested) throws java.lang.Exception
session - the session registeredisInterested - true for registering, false for removingjava.lang.Exceptionprotected abstract boolean isInterestedInRead(S session)
session - the session queriedprotected abstract boolean isInterestedInWrite(S session)
session - the session queriedprotected abstract void init(S session) throws java.lang.Exception
session - the IoSession to add to the pollingjava.lang.Exception - any exception thrown by the underlying system callsprotected abstract void destroy(S session) throws java.lang.Exception
session - the IoSessionjava.lang.Exception - any exception thrown by the underlying system callsprotected abstract int read(S session, IoBuffer buf) throws java.lang.Exception
IoSession into the given
IoBuffer. Is called when the session was found ready for reading.session - the session to readbuf - the buffer to filljava.lang.Exception - any exception thrown by the underlying system callsprotected abstract int write(S session, IoBuffer buf, int length) throws java.lang.Exception
IoSession, means to be called when
a session was found ready for writing.session - the session to writebuf - the buffer to writelength - the number of bytes to write can be superior to the number of
bytes remaining in the bufferjava.lang.Exception - any exception thrown by the underlying system callsprotected abstract int transferFile(S session, FileRegion region, int length) throws java.lang.Exception
IoSession, if the underlying API
isn't supporting system calls like sendfile(), you can throw a
UnsupportedOperationException so the file will be send using
usual write(AbstractIoSession, IoBuffer, int) call.session - the session to writeregion - the file region to writelength - the length of the portion to sendjava.lang.Exception - any exception thrown by the underlying system callspublic final void add(S session)
session to the I/O processor so that
the I/O processor starts to perform any I/O operations related
with the session.add in interface IoProcessor<S extends AbstractIoSession>session - The added sessionpublic final void remove(S session)
session from the I/O
processor so that the I/O processor closes the connection
associated with the session and releases any other related
resources.remove in interface IoProcessor<S extends AbstractIoSession>private void scheduleRemove(S session)
public void write(S session, WriteRequest writeRequest)
session.write in interface IoProcessor<S extends AbstractIoSession>session - The session we want the message to be writtenwriteRequest - the WriteRequest to writepublic final void flush(S session)
session.flush in interface IoProcessor<S extends AbstractIoSession>session - The session we want the message to be writtenprivate void scheduleFlush(S session)
public final void updateTrafficMask(S session)
session - the session to updateprivate void startupProcessor()
protected abstract void registerNewSelector()
throws java.io.IOException
java.io.IOException - If we got an exceptionprotected abstract boolean isBrokenConnection()
throws java.io.IOException
java.io.IOException - If we got an exceptionprivate int handleNewSessions()
private boolean addNow(S session)
session - The session to createprivate int removeSessions()
private boolean removeNow(S session)
private void clearWriteRequestQueue(S session)
private void process()
throws java.lang.Exception
java.lang.Exceptionprivate void process(S session)
private void read(S session)
private void notifyIdleSessions(long currentTime)
throws java.lang.Exception
java.lang.Exceptionprivate void flush(long currentTime)
private boolean flushNow(S session, long currentTime)
private int writeBuffer(S session, WriteRequest req, boolean hasFragmentation, int maxLength, long currentTime) throws java.lang.Exception
java.lang.Exceptionprivate int writeFile(S session, WriteRequest req, boolean hasFragmentation, int maxLength, long currentTime) throws java.lang.Exception
java.lang.Exceptionprivate void fireMessageSent(S session, WriteRequest req)
private void updateTrafficMask()
public void updateTrafficControl(S session)
session depending of the
IoSession.isReadSuspended() and IoSession.isWriteSuspended()
flagsupdateTrafficControl in interface IoProcessor<S extends AbstractIoSession>