Skip to content

Commit

Permalink
Unit test + jmx to track pending connections
Browse files Browse the repository at this point in the history
  • Loading branch information
vinothchandar committed Mar 14, 2012
1 parent 91a0dc2 commit 7c65ab7
Show file tree
Hide file tree
Showing 6 changed files with 154 additions and 12 deletions.
5 changes: 4 additions & 1 deletion src/java/voldemort/server/niosocket/AsyncRequestHandler.java
Expand Up @@ -352,7 +352,10 @@ private boolean initRequestHandler(SelectionKey selectionKey) {

@Override
public void close() {
if(!isClosed.compareAndSet(false, true))
return;

serverConnectionCount.decrement();
super.close();
closeInternal();
}
}
9 changes: 9 additions & 0 deletions src/java/voldemort/server/niosocket/NioSelectorManager.java
Expand Up @@ -192,4 +192,13 @@ protected void processEvents() {
public Integer getNumActiveConnections() {
return numActiveConnections.toInteger();
}

/**
* Returns the number of connections queued for registration
*
* @return
*/
public Integer getNumQueuedConnections() {
return socketChannelQueue.size();
}
}
9 changes: 9 additions & 0 deletions src/java/voldemort/server/niosocket/NioSocketService.java
Expand Up @@ -268,4 +268,13 @@ public final int getNumActiveConnections() {
return sum;
}

@JmxGetter(name = "numQueuedConnections", description = "total number of connections pending for registration with selector managers")
public final int getNumQueuedConnections() {
int sum = 0;
for(NioSelectorManager manager: selectorManagers) {
sum += manager.getNumQueuedConnections();
}
return sum;
}

}
4 changes: 4 additions & 0 deletions src/java/voldemort/utils/Props.java
Expand Up @@ -67,6 +67,10 @@ public Props(Map<String, String>... props) {

public Props(Properties... properties) {
this.props = new HashMap<String, String>();
loadProperties(properties);
}

public void loadProperties(Properties... properties) {
for(int i = properties.length - 1; i >= 0; i--)
for(Entry<Object, Object> e: properties[i].entrySet())
this.props.put((String) e.getKey(), (String) e.getValue());
Expand Down
24 changes: 13 additions & 11 deletions test/common/voldemort/ServerTestUtils.java
@@ -1,12 +1,12 @@
/*
* Copyright 2008-2009 LinkedIn, Inc
*
*
* Licensed 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
Expand All @@ -33,7 +33,6 @@

import org.apache.commons.io.FileUtils;
import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.servlet.Context;
import org.mortbay.jetty.servlet.ServletHolder;
Expand Down Expand Up @@ -82,8 +81,8 @@

/**
* Helper functions for testing with real server implementations
*
*
*
*
*/
public class ServerTestUtils {

Expand Down Expand Up @@ -211,7 +210,9 @@ public static Context getJettyServer(String clusterXml,
return context;
}

public static HttpStore getHttpStore(String storeName, RequestFormatType format, int port,
public static HttpStore getHttpStore(String storeName,
RequestFormatType format,
int port,
final HttpClient httpClient) {
return new HttpStore(storeName,
"localhost",
Expand Down Expand Up @@ -288,7 +289,7 @@ public static Cluster getLocalCluster(int numberOfNodes, int[] ports, int[][] pa
/**
* Update a cluster by replacing the specified server with a new host, i.e.
* new ports since they are all localhost
*
*
* @param original The original cluster to be updated
* @param serverIds The ids of the server to be replaced with new hosts
* @return updated cluster
Expand Down Expand Up @@ -328,7 +329,7 @@ public static Cluster updateClusterWithNewHost(Cluster original, int... serverId
/**
* Returns a list of zones with their proximity list being in increasing
* order
*
*
* @param numberOfZones The number of zones to return
* @return List of zones
*/
Expand All @@ -352,7 +353,7 @@ public static List<Zone> getZones(int numberOfZones) {
* Returns a cluster with <b>numberOfNodes</b> nodes in <b>numberOfZones</b>
* zones. It is important that <b>numberOfNodes</b> be divisible by
* <b>numberOfZones</b>
*
*
* @param numberOfNodes Number of nodes in the cluster
* @param partitionsPerNode Number of partitions in one node
* @param numberOfZones Number of zones
Expand Down Expand Up @@ -595,14 +596,15 @@ public static VoldemortConfig createServerConfig(boolean useNio,
String clusterFile,
String storeFile,
Properties properties) throws IOException {
Props props = new Props(properties);
Props props = new Props();
props.put("node.id", nodeId);
props.put("voldemort.home", baseDir + "/node-" + nodeId);
props.put("bdb.cache.size", 1 * 1024 * 1024);
props.put("bdb.write.transactions", "true");
props.put("bdb.flush.transactions", "true");
props.put("jmx.enable", "false");
props.put("enable.mysql.engine", "true");
props.loadProperties(properties);

VoldemortConfig config = new VoldemortConfig(props);
config.setMysqlDatabaseName("voldemort");
Expand Down
115 changes: 115 additions & 0 deletions test/unit/voldemort/server/socket/NioStatsJmxTest.java
@@ -0,0 +1,115 @@
/*
* Copyright 2008-2009 LinkedIn, Inc
*
* Licensed 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 voldemort.server.socket;

import java.lang.management.ManagementFactory;
import java.util.Properties;
import java.util.Random;
import java.util.concurrent.TimeUnit;

import javax.management.MBeanServer;
import javax.management.ObjectName;

import junit.framework.TestCase;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import voldemort.ServerTestUtils;
import voldemort.TestUtils;
import voldemort.client.ClientConfig;
import voldemort.cluster.Cluster;
import voldemort.cluster.Node;
import voldemort.server.VoldemortConfig;
import voldemort.server.VoldemortServer;
import voldemort.server.niosocket.NioSocketService;
import voldemort.store.Store;
import voldemort.store.socket.SocketStoreFactory;
import voldemort.store.socket.clientrequest.ClientRequestExecutorPool;
import voldemort.utils.ByteArray;
import voldemort.utils.JmxUtils;
import voldemort.versioning.Versioned;

/**
* Unit test for NIO selector connection stats
*
*/
public class NioStatsJmxTest extends TestCase {

private VoldemortServer server;
private Store<ByteArray, byte[], byte[]> socketStore;
private static final int MAX_TRAFFIC_TIME_MS = 2000;

@Override
@Before
public void setUp() throws Exception {
String storeDefinitionFile = "test/common/voldemort/config/single-store.xml";
ClientConfig clientConfig = new ClientConfig().setMaxConnectionsPerNode(1).setMaxThreads(1);
SocketStoreFactory socketStoreFactory = new ClientRequestExecutorPool(clientConfig.getSelectors(),
clientConfig.getMaxConnectionsPerNode(),
clientConfig.getConnectionTimeout(TimeUnit.MILLISECONDS),
clientConfig.getSocketTimeout(TimeUnit.MILLISECONDS),
clientConfig.getSocketBufferSize(),
clientConfig.getSocketKeepAlive());
Cluster cluster = ServerTestUtils.getLocalCluster(1);
Properties props = new Properties();
props.put("jmx.enable", "true");
VoldemortConfig config = ServerTestUtils.createServerConfig(true,
0,
TestUtils.createTempDir()
.getAbsolutePath(),
null,
storeDefinitionFile,
props);
server = ServerTestUtils.startVoldemortServer(socketStoreFactory, config, cluster);
for(Node node: cluster.getNodes()) {
socketStore = ServerTestUtils.getSocketStore(socketStoreFactory,
"test",
node.getSocketPort(),
clientConfig.getRequestFormatType());
}
}

@Test
public void testActiveConnectionCount() throws Exception {
// generate some traffic,
Random dataGen = new Random();
long start = System.currentTimeMillis();
long now = 0;

byte[] data = new byte[256];
while(((now = System.currentTimeMillis()) - start) <= MAX_TRAFFIC_TIME_MS) {
dataGen.nextBytes(data);
ByteArray key = new ByteArray(data);
socketStore.put(key, new Versioned<byte[]>(data), null);
}

// has to be 1, since we configure client with 1 connection and do
// atleast one operation
MBeanServer beanserver = ManagementFactory.getPlatformMBeanServer();
ObjectName name = JmxUtils.createObjectName(JmxUtils.getPackageName(NioSocketService.class),
"nio-socket-server");
assertEquals(1, beanserver.getAttribute(name, "numActiveConnections"));
}

@Override
@After
public void tearDown() {
server.stop();
}
}

0 comments on commit 7c65ab7

Please sign in to comment.