Author: jvermillard
Date: Wed Feb 15 15:22:50 2012
New Revision: 1244531
URL: http://svn.apache.org/viewvc?rev=1244531&view=rev
Log:
DIRMINA-850 idle checker (WIP)
Added:
mina/trunk/core/src/main/java/org/apache/mina/service/idlechecker/
mina/trunk/core/src/main/java/org/apache/mina/service/idlechecker/IdleChecker.java
(with props)
mina/trunk/core/src/main/java/org/apache/mina/service/idlechecker/IndexedIdleChecker.java
(with props)
Modified:
mina/trunk/core/src/main/java/org/apache/mina/api/IdleStatus.java
mina/trunk/core/src/main/java/org/apache/mina/api/IoSession.java
mina/trunk/core/src/main/java/org/apache/mina/api/IoSessionConfig.java
mina/trunk/core/src/main/java/org/apache/mina/session/AbstractIoSession.java
mina/trunk/core/src/main/java/org/apache/mina/transport/tcp/DefaultSocketSessionConfig.java
mina/trunk/core/src/main/java/org/apache/mina/transport/tcp/NioSelectorProcessor.java
mina/trunk/core/src/main/java/org/apache/mina/transport/tcp/ProxySocketSessionConfig.java
mina/trunk/core/src/main/java/org/apache/mina/transport/tcp/nio/NioTcpServer.java
mina/trunk/core/src/test/java/org/apache/mina/session/AbstractIoSessionTest.java
mina/trunk/core/src/test/java/org/apache/mina/transport/tcp/ProxySocketSessionConfigTest.java
Modified: mina/trunk/core/src/main/java/org/apache/mina/api/IdleStatus.java
URL:
http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/api/IdleStatus.java?rev=1244531&r1=1244530&r2=1244531&view=diff
==============================================================================
--- mina/trunk/core/src/main/java/org/apache/mina/api/IdleStatus.java (original)
+++ mina/trunk/core/src/main/java/org/apache/mina/api/IdleStatus.java Wed Feb
15 15:22:50 2012
@@ -25,13 +25,12 @@ package org.apache.mina.api;
* <ul>
* <li>{@link #READ_IDLE} - No data is coming from the remote peer.</li>
* <li>{@link #WRITE_IDLE} - Session is not writing any data.</li>
- * <li>{@link #READ_WRITE_IDLE} - Both {@link #READ_IDLE} and {@link
#WRITE_IDLE}.</li>
* </ul>
*
* @author <a href="http://mina.apache.org">Apache MINA Project</a>
*/
public enum IdleStatus {
- READ_IDLE("read idle"), WRITE_IDLE("write idle"), READ_WRITE_IDLE("both
idle");
+ READ_IDLE("read idle"), WRITE_IDLE("write idle");
private final String description;
Modified: mina/trunk/core/src/main/java/org/apache/mina/api/IoSession.java
URL:
http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/api/IoSession.java?rev=1244531&r1=1244530&r2=1244531&view=diff
==============================================================================
--- mina/trunk/core/src/main/java/org/apache/mina/api/IoSession.java (original)
+++ mina/trunk/core/src/main/java/org/apache/mina/api/IoSession.java Wed Feb 15
15:22:50 2012
@@ -266,6 +266,7 @@ public interface IoSession {
long getLastWriteTime();
/* Session context management */
+
/**
* Returns the value of the user-defined attribute for the given
* <code>key</code>.If the there is no attribute with the specified key
the <tt>defaultValue</tt> will be returned.
@@ -280,6 +281,19 @@ public interface IoSession {
<T> T getAttribute(AttributeKey<T> key, T defaultValue);
/**
+ * Returns the value of the user-defined attribute for the given
+ * <code>key</code>.If the there is no attribute with the specified key
<code>null</code> will be returned.
+ *
+ * @param key
+ * the attribute's key, must not be <code>null</code>
+ * @return <code>null</code> if there is no attribute with the specified
key
+ * @exception IllegalArgumentException
+ * if <code>key==null</code>
+ * @see #setAttribute(AttributeKey, Object)
+ */
+ <T> T getAttribute(AttributeKey<T> key);
+
+ /**
* Sets a user-defined attribute. If the <code>value</code> is
* <code>null</code> the attribute will be removed from this
* {@link IoSession}.
Modified: mina/trunk/core/src/main/java/org/apache/mina/api/IoSessionConfig.java
URL:
http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/api/IoSessionConfig.java?rev=1244531&r1=1244530&r2=1244531&view=diff
==============================================================================
--- mina/trunk/core/src/main/java/org/apache/mina/api/IoSessionConfig.java
(original)
+++ mina/trunk/core/src/main/java/org/apache/mina/api/IoSessionConfig.java Wed
Feb 15 15:22:50 2012
@@ -28,8 +28,8 @@ public interface IoSessionConfig {
/**
* Returns idle time for the specified type of idleness in milli-seconds.
- *
* @see IdleStatus
+ * @return the idle time in ms or <code>-1</code> if no idle time
configured for this status
*/
long getIdleTimeInMillis(IdleStatus status);
@@ -38,7 +38,7 @@ public interface IoSessionConfig {
* operation type (read/write/both) @see IdleStatus
*
* @param status the type of idle (read/write/both) timeout to set
- * @param ildeTimeInMilli the timeout in milliseconds
+ * @param ildeTimeInMilli the timeout in milliseconds (<code>-1</code> for
no idle detection on this status)
*/
void setIdleTimeInMillis(IdleStatus status, long ildeTimeInMilli);
Added:
mina/trunk/core/src/main/java/org/apache/mina/service/idlechecker/IdleChecker.java
URL:
http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/service/idlechecker/IdleChecker.java?rev=1244531&view=auto
==============================================================================
---
mina/trunk/core/src/main/java/org/apache/mina/service/idlechecker/IdleChecker.java
(added)
+++
mina/trunk/core/src/main/java/org/apache/mina/service/idlechecker/IdleChecker.java
Wed Feb 15 15:22:50 2012
@@ -0,0 +1,31 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.mina.service.idlechecker;
+
+import org.apache.mina.session.AbstractIoSession;
+
+public interface IdleChecker {
+
+ void sessionWritten(AbstractIoSession session, long time);
+
+ void sessionRead(AbstractIoSession session, long time);
+
+ int processIdleSession(long time);
+
+}
Propchange:
mina/trunk/core/src/main/java/org/apache/mina/service/idlechecker/IdleChecker.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added:
mina/trunk/core/src/main/java/org/apache/mina/service/idlechecker/IndexedIdleChecker.java
URL:
http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/service/idlechecker/IndexedIdleChecker.java?rev=1244531&view=auto
==============================================================================
---
mina/trunk/core/src/main/java/org/apache/mina/service/idlechecker/IndexedIdleChecker.java
(added)
+++
mina/trunk/core/src/main/java/org/apache/mina/service/idlechecker/IndexedIdleChecker.java
Wed Feb 15 15:22:50 2012
@@ -0,0 +1,165 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.mina.service.idlechecker;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.mina.api.IdleStatus;
+import org.apache.mina.session.AbstractIoSession;
+import org.apache.mina.session.AttributeKey;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class IndexedIdleChecker implements IdleChecker {
+
+ private static int MAX_IDLE_TIME_IN_SEC = 60 * 60; // 1 hour max idle
+
+ private static long MAX_IDLE_TIME_IN_MS = MAX_IDLE_TIME_IN_SEC * 1000L; //
1 hour max idle
+
+ private static final Logger LOG =
LoggerFactory.getLogger(IndexedIdleChecker.class);
+
+ private static final AttributeKey<Integer> READ_IDLE_INDEX =
AttributeKey.createKey(Integer.class,
+ "idle.read.index");
+
+ private static final AttributeKey<Integer> WRITE_IDLE_INDEX =
AttributeKey.createKey(Integer.class,
+ "idle.write.index");
+
+ private long lastCheckTime = 0L;
+
+ @SuppressWarnings("unchecked")
+ private Set<AbstractIoSession>[] readIdleSessionIndex = new
Set[MAX_IDLE_TIME_IN_SEC];
+
+ @SuppressWarnings("unchecked")
+ private Set<AbstractIoSession>[] writeIdleSessionIndex = new
Set[MAX_IDLE_TIME_IN_SEC];
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void sessionRead(AbstractIoSession session, long timeInMs) {
+ LOG.debug("session read event, compute idle index of session {}",
session);
+
+ // remove from the old index position
+ Integer oldIndex = session.getAttribute(READ_IDLE_INDEX);
+ if (oldIndex != null && readIdleSessionIndex[oldIndex] != null) {
+ LOG.debug("remove for old index {}", oldIndex);
+ readIdleSessionIndex[oldIndex].remove(session);
+ }
+
+ long idleTimeInMs =
session.getConfig().getIdleTimeInMillis(IdleStatus.READ_IDLE);
+ // is idle enabled ?
+ if (idleTimeInMs <= 0L) {
+ LOG.debug("no read idle configuration");
+ } else {
+ int nextIdleTimeInSeconds = (int) ((timeInMs + idleTimeInMs) /
1000L);
+ int index = nextIdleTimeInSeconds % MAX_IDLE_TIME_IN_SEC;
+ if (readIdleSessionIndex[index] == null) {
+ readIdleSessionIndex[index] = new HashSet<AbstractIoSession>();
+ }
+
+ readIdleSessionIndex[index].add(session);
+ session.setAttribute(READ_IDLE_INDEX, index);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void sessionWritten(AbstractIoSession session, long timeInMs) {
+ LOG.debug("session write event, compute idle index of session {}",
session);
+
+ // remove from the old index position
+ Integer oldIndex = session.getAttribute(WRITE_IDLE_INDEX);
+ if (oldIndex != null && writeIdleSessionIndex[oldIndex] != null) {
+ LOG.debug("remove for old index {}", oldIndex);
+ writeIdleSessionIndex[oldIndex].remove(session);
+ }
+
+ long idleTimeInMs =
session.getConfig().getIdleTimeInMillis(IdleStatus.WRITE_IDLE);
+ // is idle enabled ?
+ if (idleTimeInMs <= 0L) {
+ LOG.debug("no write idle configuration");
+ } else {
+ int nextIdleTimeInSeconds = (int) ((timeInMs + idleTimeInMs) /
1000L);
+ int index = nextIdleTimeInSeconds % MAX_IDLE_TIME_IN_SEC;
+ if (writeIdleSessionIndex[index] == null) {
+ writeIdleSessionIndex[index] = new
HashSet<AbstractIoSession>();
+ }
+
+ writeIdleSessionIndex[index].add(session);
+ session.setAttribute(WRITE_IDLE_INDEX, index);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int processIdleSession(long time) {
+ int counter = 0;
+ long delta = time - lastCheckTime;
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("checking idle time, last = {}, now = {}, delta = {}",
+ new Object[] { lastCheckTime, time, delta });
+ }
+
+ if (delta < 1000) {
+ LOG.debug("not a second between the last checks, abort");
+ return 0;
+ }
+
+ int startIdx = ((int) (Math.max(lastCheckTime, time -
MAX_IDLE_TIME_IN_MS) / 1000L)) % MAX_IDLE_TIME_IN_SEC;
+ int endIdx = ((int) (time / 1000L)) % MAX_IDLE_TIME_IN_SEC;
+
+ for (int index = startIdx; index != endIdx; index = (index + 1) %
MAX_IDLE_TIME_IN_SEC) {
+ // look at the read idle index
+ counter += processIndex(readIdleSessionIndex, index,
IdleStatus.READ_IDLE);
+ counter += processIndex(writeIdleSessionIndex, index,
IdleStatus.WRITE_IDLE);
+
+ }
+ // save last check time for next call
+ lastCheckTime = time;
+ LOG.debug("detected {} idleing sessions", counter);
+ return counter;
+ }
+
+ private int processIndex(Set<AbstractIoSession>[] indexByTime, int
position, IdleStatus status) {
+ Set<AbstractIoSession> sessions = indexByTime[position];
+ if (sessions == null) {
+ return 0;
+ }
+
+ int counter = 0;
+
+ for (AbstractIoSession idleSession : sessions) {
+ idleSession.setAttribute(status == IdleStatus.READ_IDLE ?
READ_IDLE_INDEX : WRITE_IDLE_INDEX, null);
+ // check if idle detection wasn't disabled since the index update
+ if (idleSession.getConfig().getIdleTimeInMillis(status) > 0) {
+ idleSession.processSessionIdle(status);
+ }
+ counter++;
+ }
+ // clear the processed index entry
+ indexByTime[position] = null;
+ return counter;
+ }
+}
Propchange:
mina/trunk/core/src/main/java/org/apache/mina/service/idlechecker/IndexedIdleChecker.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified:
mina/trunk/core/src/main/java/org/apache/mina/session/AbstractIoSession.java
URL:
http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/session/AbstractIoSession.java?rev=1244531&r1=1244530&r2=1244531&view=diff
==============================================================================
---
mina/trunk/core/src/main/java/org/apache/mina/session/AbstractIoSession.java
(original)
+++
mina/trunk/core/src/main/java/org/apache/mina/session/AbstractIoSession.java
Wed Feb 15 15:22:50 2012
@@ -24,7 +24,7 @@ import java.util.Collections;
import java.util.Queue;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@@ -32,6 +32,7 @@ import java.util.concurrent.locks.Reentr
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
+import org.apache.mina.api.IdleStatus;
import org.apache.mina.api.IoFilter;
import org.apache.mina.api.IoFuture;
import org.apache.mina.api.IoService;
@@ -52,7 +53,7 @@ public abstract class AbstractIoSession
private static final Logger LOG =
LoggerFactory.getLogger(AbstractIoSession.class);
/** unique identifier generator */
- private static final AtomicLong NEXT_ID = new AtomicLong(0);
+ private static final AtomicInteger NEXT_ID = new AtomicInteger(0);
/** The session's unique identifier */
private final long id;
@@ -378,6 +379,14 @@ public abstract class AbstractIoSession
}
/**
+ * To be called by the internal plumber when some bytes are written on the
socket
+ * @param bytesCount number of extra bytes written
+ */
+ public void incrementWrittenBytes(int bytesCount) {
+ writtenBytes += bytesCount;
+ }
+
+ /**
* {@inheritDoc}
*/
@Override
@@ -431,6 +440,17 @@ public abstract class AbstractIoSession
/**
* {@inheritDoc}
*
+ * @exception IllegalArgumentException if <code>key==null</code>
+ * @see #setAttribute(AttributeKey, Object)
+ */
+ @Override
+ public final <T> T getAttribute(AttributeKey<T> key) {
+ return attributes.getAttribute(key);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
* @exception IllegalArgumentException
* <ul>
* <li>
@@ -598,6 +618,17 @@ public abstract class AbstractIoSession
}
/**
+ * process session idle event using the filter chain. To be called by the
session {@link SelectorProcessor} .
+ */
+ public void processSessionIdle(IdleStatus status) {
+ LOG.debug("processing session idle {} event for session {}", status,
this);
+
+ for (IoFilter filter : chain) {
+ filter.sessionIdle(this, status);
+ }
+ }
+
+ /**
* process session message received event using the filter chain. To be
called by the session {@link SelectorProcessor} .
* @param message the received message
*/
Modified:
mina/trunk/core/src/main/java/org/apache/mina/transport/tcp/DefaultSocketSessionConfig.java
URL:
http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/transport/tcp/DefaultSocketSessionConfig.java?rev=1244531&r1=1244530&r2=1244531&view=diff
==============================================================================
---
mina/trunk/core/src/main/java/org/apache/mina/transport/tcp/DefaultSocketSessionConfig.java
(original)
+++
mina/trunk/core/src/main/java/org/apache/mina/transport/tcp/DefaultSocketSessionConfig.java
Wed Feb 15 15:22:50 2012
@@ -37,8 +37,9 @@ public class DefaultSocketSessionConfig
private long idleTimeWrite = -1;
- private long idleTimeReadWrite = -1;
-
+ /**
+ * {@inheritDoc}
+ */
@Override
public long getIdleTimeInMillis(IdleStatus status) {
switch (status) {
@@ -46,13 +47,14 @@ public class DefaultSocketSessionConfig
return idleTimeRead;
case WRITE_IDLE:
return idleTimeWrite;
- case READ_WRITE_IDLE:
- return idleTimeReadWrite;
default:
throw new RuntimeException("unexpected excetion, unknown idle
status : " + status);
}
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public void setIdleTimeInMillis(IdleStatus status, long ildeTimeInMilli) {
switch (status) {
@@ -62,9 +64,6 @@ public class DefaultSocketSessionConfig
case WRITE_IDLE:
this.idleTimeWrite = ildeTimeInMilli;
break;
- case READ_WRITE_IDLE:
- this.idleTimeReadWrite = ildeTimeInMilli;
- break;
default:
throw new RuntimeException("unexpected excetion, unknown idle
status : " + status);
}
@@ -76,11 +75,17 @@ public class DefaultSocketSessionConfig
private Integer receiveBufferSize = null;
+ /**
+ * {@inheritDoc}
+ */
@Override
public Integer getReceiveBufferSize() {
return receiveBufferSize;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public void setReceiveBufferSize(int receiveBufferSize) {
this.receiveBufferSize = receiveBufferSize;
@@ -88,11 +93,17 @@ public class DefaultSocketSessionConfig
private Integer sendBufferSize = null;
+ /**
+ * {@inheritDoc}
+ */
@Override
public Integer getSendBufferSize() {
return sendBufferSize;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public void setSendBufferSize(int sendBufferSize) {
this.sendBufferSize = sendBufferSize;
@@ -104,11 +115,17 @@ public class DefaultSocketSessionConfig
private Boolean tcpNoDelay = null;
+ /**
+ * {@inheritDoc}
+ */
@Override
public Boolean isTcpNoDelay() {
return tcpNoDelay;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public void setTcpNoDelay(boolean tcpNoDelay) {
this.tcpNoDelay = tcpNoDelay;
@@ -116,11 +133,17 @@ public class DefaultSocketSessionConfig
private Boolean reuseAddress = null;
+ /**
+ * {@inheritDoc}
+ */
@Override
public Boolean isReuseAddress() {
return reuseAddress;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public void setReuseAddress(boolean reuseAddress) {
this.reuseAddress = reuseAddress;
@@ -128,11 +151,17 @@ public class DefaultSocketSessionConfig
private Integer trafficClass;
+ /**
+ * {@inheritDoc}
+ */
@Override
public Integer getTrafficClass() {
return trafficClass;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public void setTrafficClass(int trafficClass) {
this.trafficClass = trafficClass;
@@ -140,11 +169,17 @@ public class DefaultSocketSessionConfig
private Boolean keepAlive = null;
+ /**
+ * {@inheritDoc}
+ */
@Override
public Boolean isKeepAlive() {
return keepAlive;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public void setKeepAlive(boolean keepAlive) {
this.keepAlive = keepAlive;
@@ -152,11 +187,17 @@ public class DefaultSocketSessionConfig
private Boolean oobInline = null;
+ /**
+ * {@inheritDoc}
+ */
@Override
public Boolean isOobInline() {
return oobInline;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public void setOobInline(boolean oobInline) {
this.oobInline = oobInline;
@@ -165,11 +206,17 @@ public class DefaultSocketSessionConfig
private Integer soLinger;
+ /**
+ * {@inheritDoc}
+ */
@Override
public Integer getSoLinger() {
return soLinger;
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public void setSoLinger(int soLinger) {
this.soLinger = soLinger;
Modified:
mina/trunk/core/src/main/java/org/apache/mina/transport/tcp/NioSelectorProcessor.java
URL:
http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/transport/tcp/NioSelectorProcessor.java?rev=1244531&r1=1244530&r2=1244531&view=diff
==============================================================================
---
mina/trunk/core/src/main/java/org/apache/mina/transport/tcp/NioSelectorProcessor.java
(original)
+++
mina/trunk/core/src/main/java/org/apache/mina/transport/tcp/NioSelectorProcessor.java
Wed Feb 15 15:22:50 2012
@@ -40,6 +40,7 @@ import java.util.concurrent.locks.Reentr
import javax.net.ssl.SSLException;
+import org.apache.mina.api.IdleStatus;
import org.apache.mina.api.IoServer;
import org.apache.mina.api.IoService;
import org.apache.mina.api.IoSession;
@@ -47,6 +48,8 @@ import org.apache.mina.api.RuntimeIoExce
import org.apache.mina.service.AbstractIoService;
import org.apache.mina.service.SelectorProcessor;
import org.apache.mina.service.SelectorStrategy;
+import org.apache.mina.service.idlechecker.IdleChecker;
+import org.apache.mina.service.idlechecker.IndexedIdleChecker;
import org.apache.mina.session.AbstractIoSession;
import org.apache.mina.session.DefaultWriteFuture;
import org.apache.mina.session.SslHelper;
@@ -80,6 +83,9 @@ public class NioSelectorProcessor implem
/** the thread polling and processing the I/O events */
private SelectorWorker worker = null;
+ /** helper for detecting idleing sessions */
+ private IdleChecker idleChecker = new IndexedIdleChecker();
+
/** A queue containing the servers to bind to this selector */
private final Queue<Object[]> serversToAdd = new
ConcurrentLinkedQueue<Object[]>();
@@ -185,6 +191,11 @@ public class NioSelectorProcessor implem
LOGGER.error("Unexpected exception, while configuring socket as
non blocking", e);
throw new RuntimeIoException("cannot configure socket as
non-blocking", e);
}
+ // apply idle configuration
+ session.getConfig().setIdleTimeInMillis(IdleStatus.READ_IDLE,
+ defaultConfig.getIdleTimeInMillis(IdleStatus.READ_IDLE));
+ session.getConfig().setIdleTimeInMillis(IdleStatus.WRITE_IDLE,
+ defaultConfig.getIdleTimeInMillis(IdleStatus.WRITE_IDLE));
// apply the default service socket configuration
Boolean keepAlive = defaultConfig.isKeepAlive();
@@ -360,6 +371,9 @@ public class NioSelectorProcessor implem
} finally {
workerLock.unlock();
}
+
+ // check for idle events
+ idleChecker.processIdleSession(System.currentTimeMillis());
}
} catch (Exception e) {
LOGGER.error("Unexpected exception : ", e);
@@ -414,6 +428,9 @@ public class NioSelectorProcessor implem
// fire the event
((AbstractIoService)
session.getService()).fireSessionCreated(session);
session.processSessionOpened();
+ long time = System.currentTimeMillis();
+ idleChecker.sessionRead(session, time);
+ idleChecker.sessionWritten(session, time);
}
}
}
@@ -485,6 +502,8 @@ public class NioSelectorProcessor implem
// Plain message, not encrypted : go directly to the chain
session.processMessageReceived(readBuffer);
}
+
+ idleChecker.sessionRead(session, System.currentTimeMillis());
}
}
@@ -517,10 +536,10 @@ public class NioSelectorProcessor implem
// Note that if the connection is secured, the buffer
already
// contains encrypted data.
int wrote = session.getSocketChannel().write(buf);
+ session.incrementWrittenBytes(wrote);
+ LOGGER.debug("wrote {} bytes to {}", wrote, session);
- if (LOGGER.isDebugEnabled()) {
- LOGGER.debug("wrote {} bytes to {}", wrote, session);
- }
+ idleChecker.sessionWritten(session,
System.currentTimeMillis());
if (buf.remaining() == 0) {
// completed write request, let's remove it
Modified:
mina/trunk/core/src/main/java/org/apache/mina/transport/tcp/ProxySocketSessionConfig.java
URL:
http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/transport/tcp/ProxySocketSessionConfig.java?rev=1244531&r1=1244530&r2=1244531&view=diff
==============================================================================
---
mina/trunk/core/src/main/java/org/apache/mina/transport/tcp/ProxySocketSessionConfig.java
(original)
+++
mina/trunk/core/src/main/java/org/apache/mina/transport/tcp/ProxySocketSessionConfig.java
Wed Feb 15 15:22:50 2012
@@ -45,23 +45,24 @@ public class ProxySocketSessionConfig im
private long idleTimeWrite = -1;
- private long idleTimeReadWrite = -1;
-
+ /**
+ * {@inheritDoc}
+ */
@Override
public long getIdleTimeInMillis(IdleStatus status) {
switch (status) {
case READ_IDLE:
return idleTimeRead;
-
case WRITE_IDLE:
return idleTimeWrite;
- case READ_WRITE_IDLE:
- return idleTimeReadWrite;
default:
throw new RuntimeException("unexpected excetion, unknown idle
status : " + status);
}
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public void setIdleTimeInMillis(IdleStatus status, long ildeTimeInMilli) {
switch (status) {
@@ -71,14 +72,14 @@ public class ProxySocketSessionConfig im
case WRITE_IDLE:
this.idleTimeWrite = ildeTimeInMilli;
break;
- case READ_WRITE_IDLE:
- this.idleTimeReadWrite = ildeTimeInMilli;
- break;
default:
throw new RuntimeException("unexpected excetion, unknown idle
status : " + status);
}
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public Boolean isTcpNoDelay() {
try {
@@ -88,6 +89,9 @@ public class ProxySocketSessionConfig im
}
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public void setTcpNoDelay(boolean tcpNoDelay) {
LOG.debug("set TCP no delay '{}' for session '{}'", tcpNoDelay, this);
@@ -98,6 +102,9 @@ public class ProxySocketSessionConfig im
}
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public Boolean isReuseAddress() {
try {
@@ -107,6 +114,9 @@ public class ProxySocketSessionConfig im
}
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public void setReuseAddress(boolean reuseAddress) {
LOG.debug("set reuse address '{}' for session '{}'", reuseAddress,
this);
@@ -117,6 +127,9 @@ public class ProxySocketSessionConfig im
}
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public Integer getReceiveBufferSize() {
try {
@@ -126,6 +139,9 @@ public class ProxySocketSessionConfig im
}
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public void setReceiveBufferSize(int receiveBufferSize) {
LOG.debug("set receive buffer size '{}' for session '{}'",
receiveBufferSize, this);
@@ -136,6 +152,9 @@ public class ProxySocketSessionConfig im
}
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public Integer getSendBufferSize() {
try {
@@ -145,6 +164,9 @@ public class ProxySocketSessionConfig im
}
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public void setSendBufferSize(int sendBufferSize) {
LOG.debug("set send buffer size '{}' for session '{}'",
sendBufferSize, this);
@@ -155,6 +177,9 @@ public class ProxySocketSessionConfig im
}
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public Integer getTrafficClass() {
try {
@@ -164,6 +189,9 @@ public class ProxySocketSessionConfig im
}
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public void setTrafficClass(int trafficClass) {
LOG.debug("set traffic class '{}' for session '{}'", trafficClass,
this);
@@ -174,6 +202,9 @@ public class ProxySocketSessionConfig im
}
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public Boolean isKeepAlive() {
try {
@@ -183,6 +214,9 @@ public class ProxySocketSessionConfig im
}
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public void setKeepAlive(boolean keepAlive) {
LOG.debug("set keep alive '{}' for session '{}'", keepAlive, this);
@@ -193,6 +227,9 @@ public class ProxySocketSessionConfig im
}
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public Boolean isOobInline() {
try {
@@ -202,6 +239,9 @@ public class ProxySocketSessionConfig im
}
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public void setOobInline(boolean oobInline) {
LOG.debug("set oob inline '{}' for session '{}'", oobInline, this);
@@ -212,6 +252,9 @@ public class ProxySocketSessionConfig im
}
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public Integer getSoLinger() {
try {
@@ -221,6 +264,9 @@ public class ProxySocketSessionConfig im
}
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public void setSoLinger(int soLinger) {
LOG.debug("set so linger '{}' for session '{}'", soLinger, this);
Modified:
mina/trunk/core/src/main/java/org/apache/mina/transport/tcp/nio/NioTcpServer.java
URL:
http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/transport/tcp/nio/NioTcpServer.java?rev=1244531&r1=1244530&r2=1244531&view=diff
==============================================================================
---
mina/trunk/core/src/main/java/org/apache/mina/transport/tcp/nio/NioTcpServer.java
(original)
+++
mina/trunk/core/src/main/java/org/apache/mina/transport/tcp/nio/NioTcpServer.java
Wed Feb 15 15:22:50 2012
@@ -26,6 +26,8 @@ import java.util.HashSet;
import java.util.Set;
import org.apache.mina.service.SelectorStrategy;
+import org.apache.mina.service.idlechecker.IdleChecker;
+import org.apache.mina.service.idlechecker.IndexedIdleChecker;
import org.apache.mina.transport.tcp.AbstractTcpServer;
import org.apache.mina.transport.tcp.DefaultSocketSessionConfig;
import org.apache.mina.transport.tcp.NioSelectorProcessor;
@@ -41,6 +43,9 @@ import org.slf4j.LoggerFactory;
public class NioTcpServer extends AbstractTcpServer {
static final Logger LOG = LoggerFactory.getLogger(NioTcpServer.class);
+ // the idle checker is used for detecting read or write idle session
+ private IdleChecker idleChecker = new IndexedIdleChecker();
+
// list of bound addresses
private Set<SocketAddress> addresses = Collections.synchronizedSet(new
HashSet<SocketAddress>());
Modified:
mina/trunk/core/src/test/java/org/apache/mina/session/AbstractIoSessionTest.java
URL:
http://svn.apache.org/viewvc/mina/trunk/core/src/test/java/org/apache/mina/session/AbstractIoSessionTest.java?rev=1244531&r1=1244530&r2=1244531&view=diff
==============================================================================
---
mina/trunk/core/src/test/java/org/apache/mina/session/AbstractIoSessionTest.java
(original)
+++
mina/trunk/core/src/test/java/org/apache/mina/session/AbstractIoSessionTest.java
Wed Feb 15 15:22:50 2012
@@ -223,6 +223,14 @@ public class AbstractIoSessionTest {
verify(filter3).sessionClosed(eq(session));
}
+ @Test
+ public void increment_written_bytes() {
+ DummySession session = new DummySession(service);
+ assertEquals(0, session.getWrittenBytes());
+ session.incrementWrittenBytes(1024);
+ assertEquals(1024, session.getWrittenBytes());
+ }
+
private class PassthruFilter extends DefaultIoFilter {
}
Modified:
mina/trunk/core/src/test/java/org/apache/mina/transport/tcp/ProxySocketSessionConfigTest.java
URL:
http://svn.apache.org/viewvc/mina/trunk/core/src/test/java/org/apache/mina/transport/tcp/ProxySocketSessionConfigTest.java?rev=1244531&r1=1244530&r2=1244531&view=diff
==============================================================================
---
mina/trunk/core/src/test/java/org/apache/mina/transport/tcp/ProxySocketSessionConfigTest.java
(original)
+++
mina/trunk/core/src/test/java/org/apache/mina/transport/tcp/ProxySocketSessionConfigTest.java
Wed Feb 15 15:22:50 2012
@@ -51,22 +51,17 @@ public class ProxySocketSessionConfigTes
@Test
public void idle() {
assertEquals(-1, config.getIdleTimeInMillis(IdleStatus.READ_IDLE));
- assertEquals(-1,
config.getIdleTimeInMillis(IdleStatus.READ_WRITE_IDLE));
assertEquals(-1, config.getIdleTimeInMillis(IdleStatus.WRITE_IDLE));
config.setIdleTimeInMillis(IdleStatus.READ_IDLE, 1);
assertEquals(1, config.getIdleTimeInMillis(IdleStatus.READ_IDLE));
- assertEquals(-1,
config.getIdleTimeInMillis(IdleStatus.READ_WRITE_IDLE));
assertEquals(-1, config.getIdleTimeInMillis(IdleStatus.WRITE_IDLE));
- config.setIdleTimeInMillis(IdleStatus.READ_WRITE_IDLE, 2);
assertEquals(1, config.getIdleTimeInMillis(IdleStatus.READ_IDLE));
- assertEquals(2,
config.getIdleTimeInMillis(IdleStatus.READ_WRITE_IDLE));
assertEquals(-1, config.getIdleTimeInMillis(IdleStatus.WRITE_IDLE));
config.setIdleTimeInMillis(IdleStatus.WRITE_IDLE, 3);
assertEquals(1, config.getIdleTimeInMillis(IdleStatus.READ_IDLE));
- assertEquals(2,
config.getIdleTimeInMillis(IdleStatus.READ_WRITE_IDLE));
assertEquals(3, config.getIdleTimeInMillis(IdleStatus.WRITE_IDLE));
}