Skip to content

Commit

Permalink
Merge pull request #162 from v-xiangs/ExecutorService-instead-of-Thread
Browse files Browse the repository at this point in the history
Executor service instead of thread
  • Loading branch information
v-nisidh authored Mar 10, 2017
2 parents a53054d + a9d41cc commit e4095e2
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 8 deletions.
16 changes: 14 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -114,15 +114,27 @@
<artifactId>junit-jupiter-engine</artifactId>
<version>5.0.0-M3</version>
<scope>test</scope>
</dependency>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>2.6.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2 </artifactId>
<version>2.1.1</version>
<scope>test</scope>
</dependency>
<!--
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>4.12.0-M3</version>
<scope>test</scope>
</dependency>
-->
-->
</dependencies>

<profiles>
Expand Down
28 changes: 22 additions & 6 deletions src/main/java/com/microsoft/sqlserver/jdbc/IOBuffer.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,11 @@
import java.util.Set;
import java.util.SimpleTimeZone;
import java.util.TimeZone;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
Expand Down Expand Up @@ -6827,9 +6831,23 @@ final void TryProcessFeatureExtAck(boolean featureExtAckReceived) throws SQLServ
* a reason like "timed out".
*/
final class TimeoutTimer implements Runnable {
private static final String threadGroupName = "mssql-jdbc-TimeoutTimer";
private final int timeoutSeconds;
private final TDSCommand command;
private Thread timerThread;
private volatile Future<?> task;

private static final ExecutorService executor = Executors.newCachedThreadPool(new ThreadFactory() {
private final ThreadGroup tg = new ThreadGroup(threadGroupName);
private final String threadNamePrefix = tg.getName() + "-";
private final AtomicInteger threadNumber = new AtomicInteger(0);
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(tg, r, threadNamePrefix + threadNumber.incrementAndGet());
t.setDaemon(true);
return t;
}
});

private volatile boolean canceled = false;

TimeoutTimer(int timeoutSeconds,
Expand All @@ -6842,17 +6860,15 @@ final class TimeoutTimer implements Runnable {
}

final void start() {
timerThread = new Thread(this);
timerThread.setDaemon(true);
timerThread.start();
task = executor.submit(this);
}

final void stop() {
task.cancel(true);
canceled = true;
timerThread.interrupt();
}

public void run() {
public void run() {
int secondsRemaining = timeoutSeconds;
try {
// Poll every second while time is left on the timer.
Expand Down
108 changes: 108 additions & 0 deletions src/test/java/com/microsoft/sqlserver/jdbc/connection/PoolingTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,20 @@
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assumptions.assumeTrue;

import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.UUID;

import javax.sql.DataSource;
import javax.sql.PooledConnection;

import org.apache.commons.dbcp2.BasicDataSource;
import org.junit.jupiter.api.Test;
import org.junit.platform.runner.JUnitPlatform;
import org.junit.runner.RunWith;
Expand All @@ -30,7 +36,13 @@
import com.microsoft.sqlserver.testframework.DBConnection;
import com.microsoft.sqlserver.testframework.DBTable;
import com.microsoft.sqlserver.testframework.util.RandomUtil;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;

/**
* Tests pooled connection
*
*/
@RunWith(JUnitPlatform.class)
public class PoolingTest extends AbstractTest {
@Test
Expand Down Expand Up @@ -139,4 +151,100 @@ public void testConnectionPoolClientConnectionId() throws SQLException {

assertEquals(Id1, Id2, "ClientConnection Ids from pool are not the same.");
}

/**
* test connection pool with HikariCP
*
* @throws SQLException
*/
@Test
public void testHikariCP() throws SQLException {
HikariConfig config = new HikariConfig();
config.setJdbcUrl(connectionString);
HikariDataSource ds = new HikariDataSource(config);

try{
connect(ds);
}
finally{
ds.close();
}
}

/**
* test connection pool with Apache DBCP
*
* @throws SQLException
*/
@Test
public void testApacheDBCP() throws SQLException {
BasicDataSource ds = new BasicDataSource();
ds.setUrl(connectionString);

try{
connect(ds);
}
finally{
ds.close();
}
}


/**
* setup connection, get connection from pool, and test threads
*
* @param ds
* @throws SQLException
*/
private static void connect(DataSource ds) throws SQLException {
Connection con = null;
PreparedStatement pst = null;
ResultSet rs = null;

try {
con = ds.getConnection();
pst = con.prepareStatement("SELECT SUSER_SNAME()");
pst.setQueryTimeout(5);
rs = pst.executeQuery();

assertTrue(countTimeoutThreads() >= 1, "Timeout timer is missing.");

while (rs.next()) {
rs.getString(1);
}
}
finally {
if (rs != null) {
rs.close();
}

if (pst != null) {
pst.close();
}

if (con != null) {
con.close();
}
}
}

/**
* count number of mssql-jdbc-TimeoutTimer threads
*
* @return
*/
private static int countTimeoutThreads() {
int count = 0;
String threadName = "mssql-jdbc-TimeoutTimer";

ThreadInfo[] tinfos = ManagementFactory.getThreadMXBean().getThreadInfo(ManagementFactory.getThreadMXBean().getAllThreadIds(), 0);

for (ThreadInfo ti : tinfos) {
if ((ti.getThreadName().startsWith(threadName)) && (ti.getThreadState().equals(java.lang.Thread.State.TIMED_WAITING))) {
count++;
}
}

return count;
}
}

0 comments on commit e4095e2

Please sign in to comment.