Skip to content
This repository was archived by the owner on Feb 16, 2023. It is now read-only.

Commit a385165

Browse files
committed
Adding a fake traffic daemon thread
1 parent 9623cb7 commit a385165

File tree

1 file changed

+151
-0
lines changed

1 file changed

+151
-0
lines changed

src/com/meetup/memcached/SockIOPool.java

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ protected MessageDigest initialValue() {
159159

160160
// Pool data
161161
private MaintThread maintThread;
162+
private TrafficThread trafficThread;
162163
private boolean initialized = false;
163164
private int maxCreate = 1; // this will be initialized by pool when the pool is initialized
164165

@@ -170,6 +171,7 @@ protected MessageDigest initialValue() {
170171
private long maxIdle = 1000 * 60 * 5; // max idle time for avail sockets
171172
private long maxBusyTime = 1000 * 30; // max idle time for avail sockets
172173
private long maintSleep = 1000 * 30; // maintenance thread sleep time
174+
private long traffictSleep = 1000 * 120;
173175
private int socketTO = 1000 * 3; // default timeout of socket reads
174176
private int socketConnectTO = 1000 * 3; // default timeout of socket connections
175177
private boolean aliveCheck = false; // default to not check each connection for being alive
@@ -346,6 +348,22 @@ public static SockIOPool getInstance() {
346348
*/
347349
public long getMaintSleep() { return this.maintSleep; }
348350

351+
352+
/**
353+
* Set the sleep time between runs of the pool traffic thread.
354+
* If set to 0, then the traffic thread will not be started.
355+
*
356+
* @param maintSleep sleep time in ms
357+
*/
358+
public void setTraffictSleep( long traffictSleep ) { this.traffictSleep = traffictSleep; }
359+
360+
/**
361+
* Returns the current traffic thread sleep time.
362+
*
363+
* @return sleep time in ms
364+
*/
365+
public long getTraffictSleep() { return this.traffictSleep; }
366+
349367
/**
350368
* Sets the socket timeout for reads.
351369
*
@@ -637,6 +655,10 @@ public void initialize() {
637655
// start maint thread
638656
if ( this.maintSleep > 0 )
639657
this.startMaintThread();
658+
659+
if ( this.traffictSleep > 0 ) {
660+
this.startTrafficThread();
661+
}
640662
}
641663
}
642664

@@ -1282,6 +1304,74 @@ protected void stopMaintThread() {
12821304
maintThread.stopThread();
12831305
}
12841306

1307+
1308+
/**
1309+
* Starts the traffic thread.
1310+
*
1311+
* This thread will send fake traffic to ELB<br/>
1312+
* in order to avoid ELB closing the connection<br/>
1313+
* after an idle time.
1314+
*/
1315+
protected void startTrafficThread() {
1316+
1317+
if ( trafficThread != null ) {
1318+
1319+
if ( trafficThread.isRunning() ) {
1320+
log.error( "traffic thread already running" );
1321+
}
1322+
else {
1323+
trafficThread.start();
1324+
}
1325+
}
1326+
else {
1327+
trafficThread = new TrafficThread( this );
1328+
trafficThread.setInterval( this.traffictSleep );
1329+
trafficThread.start();
1330+
}
1331+
}
1332+
1333+
/**
1334+
* Stops the traffic thread.
1335+
*/
1336+
protected void stopTrafficThread() {
1337+
if ( trafficThread != null && trafficThread.isRunning() )
1338+
trafficThread.stopThread();
1339+
}
1340+
1341+
1342+
/**
1343+
*Fake traffic on avaliable pool to avoid ELB idle timeout
1344+
*
1345+
* This is typically called by the traffic thread to fake traffic.
1346+
*/
1347+
protected void sendTrafficToAvailablePool() {
1348+
if ( log.isDebugEnabled() )
1349+
log.debug( "++++ Traffic thread started" );
1350+
1351+
synchronized( this ) {
1352+
if ( availPool != null && !availPool.isEmpty() ) {
1353+
for (Iterator<String> i = availPool.keySet().iterator(); i.hasNext(); ) {
1354+
String host = i.next();
1355+
Map<SockIO, Long> sockets = availPool.get(host);
1356+
1357+
for (Iterator<SockIO> j = sockets.keySet().iterator(); j.hasNext(); ) {
1358+
SockIO socket = j.next();
1359+
try {
1360+
socket.write( "version\r\n".getBytes() );
1361+
socket.flush();
1362+
1363+
if (log.isDebugEnabled())
1364+
log.debug("Version: " + socket.readLine());
1365+
} catch ( IOException ex ) {
1366+
if (log.isDebugEnabled())
1367+
log.debug("Fake traffic: " + ex);
1368+
}
1369+
}
1370+
}
1371+
}
1372+
}
1373+
}
1374+
12851375
/**
12861376
* Runs self maintenance on all internal pools.
12871377
*
@@ -1504,6 +1594,67 @@ public void run() {
15041594
}
15051595
}
15061596

1597+
/**
1598+
* Class which extends thread and send traffic to ELB by period.
1599+
*
1600+
*/
1601+
protected static class TrafficThread extends Thread {
1602+
1603+
// logger
1604+
private static Logger log =
1605+
Logger.getLogger( TrafficThread.class.getName() );
1606+
1607+
private SockIOPool pool;
1608+
private long intervalFakeTraffic = 10000 * 3; // every 3 seconds
1609+
private boolean stopThread = false;
1610+
private boolean running;
1611+
1612+
protected TrafficThread( SockIOPool pool ) {
1613+
this.pool = pool;
1614+
this.setDaemon( true );
1615+
this.setName( "TrafficThread" );
1616+
}
1617+
1618+
public void setInterval( long interval ) { this.intervalFakeTraffic = interval; }
1619+
1620+
public boolean isRunning() {
1621+
return this.running;
1622+
}
1623+
1624+
/**
1625+
* sets stop variable
1626+
* and interupts any wait
1627+
*/
1628+
public void stopThread() {
1629+
this.stopThread = true;
1630+
this.interrupt();
1631+
}
1632+
1633+
/**
1634+
* Start the thread.
1635+
*/
1636+
public void run() {
1637+
this.running = true;
1638+
1639+
while ( !this.stopThread ) {
1640+
try {
1641+
Thread.sleep( intervalFakeTraffic );
1642+
1643+
// if pool is initialized, then
1644+
// run the sendTrafficToAvailablePool method on itself
1645+
if ( pool.isInitialized() )
1646+
pool.sendTrafficToAvailablePool();
1647+
1648+
}
1649+
catch ( Exception e ) {
1650+
break;
1651+
}
1652+
}
1653+
1654+
this.running = false;
1655+
}
1656+
}
1657+
15071658
/**
15081659
* MemCached client for Java, utility class for Socket IO.
15091660
*

0 commit comments

Comments
 (0)