Skip to content

Commit 956baa3

Browse files
author
mengli
committed
Fix "Too many open file" exception when the thread number is much larger than the max connection pool size.
1 parent fd64e98 commit 956baa3

File tree

2 files changed

+30
-10
lines changed

2 files changed

+30
-10
lines changed

src/main/com/schooner/MemCached/SchoonerSockIOPool.java

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -396,9 +396,9 @@ protected final SchoonerSockIO createSocket(String host) {
396396
SchoonerSockIO socket = null;
397397
try {
398398
if (isTcp) {
399-
socket = new TCPSockIO(this, host, bufferSize, this.socketTO, this.socketConnectTO, this.nagle);
399+
socket = new TCPSockIO(this, host, bufferSize, this.socketTO, this.socketConnectTO, this.nagle, false);
400400
} else {
401-
socket = new UDPSockIO(this, host, bufferSize, socketTO);
401+
socket = new UDPSockIO(this, host, bufferSize, socketTO, false);
402402
}
403403
} catch (Exception ex) {
404404
log.error("++++ failed to get SockIO obj for: " + host);
@@ -415,9 +415,9 @@ protected final SchoonerSockIO createSocketWithAdd(String host) {
415415
try {
416416
poolCurrentConn.get(host).addAndGet(1);
417417
if (isTcp) {
418-
socket = new TCPSockIO(this, host, bufferSize, this.socketTO, this.socketConnectTO, this.nagle);
418+
socket = new TCPSockIO(this, host, bufferSize, this.socketTO, this.socketConnectTO, this.nagle, true);
419419
} else {
420-
socket = new UDPSockIO(this, host, bufferSize, socketTO);
420+
socket = new UDPSockIO(this, host, bufferSize, socketTO, true);
421421
}
422422
} catch (Exception ex) {
423423
log.error("++++ failed to get SockIO obj for: " + host);
@@ -1150,7 +1150,7 @@ public void trueClose() throws IOException {
11501150
this.sockNum.decrementAndGet();
11511151
}
11521152

1153-
public UDPSockIO(SchoonerSockIOPool pool, String host, int bufferSize, int timeout) throws IOException,
1153+
public UDPSockIO(SchoonerSockIOPool pool, String host, int bufferSize, int timeout, boolean isPooled) throws IOException,
11541154
UnknownHostException {
11551155
super(bufferSize);
11561156

@@ -1162,7 +1162,10 @@ public UDPSockIO(SchoonerSockIOPool pool, String host, int bufferSize, int timeo
11621162
channel.socket().setSoTimeout(timeout);
11631163
selector = Selector.open();
11641164
((DatagramChannel) channel).register(selector, SelectionKey.OP_READ);
1165-
writeBuf = ByteBuffer.allocateDirect(bufferSize);
1165+
if (isPooled)
1166+
writeBuf = ByteBuffer.allocateDirect(bufferSize);
1167+
else
1168+
writeBuf = ByteBuffer.allocate(bufferSize);
11661169
sockets = pool.socketPool.get(host);
11671170
sockNum = pool.poolCurrentConn.get(host);
11681171
}
@@ -1292,6 +1295,13 @@ public void close() {
12921295
writeBuf.clear();
12931296
if (isPooled)
12941297
sockets.add(this);
1298+
else {
1299+
try {
1300+
trueClose();
1301+
} catch (IOException e) {
1302+
log.error("++++ error closing socket: " + toString() + " for host: " + getHost());
1303+
}
1304+
}
12951305
}
12961306

12971307
public String getHost() {
@@ -1368,7 +1378,7 @@ public static class TCPSockIO extends SchoonerSockIO {
13681378
* if hostname is invalid
13691379
*/
13701380
public TCPSockIO(SchoonerSockIOPool pool, String host, int bufferSize, int timeout, int connectTimeout,
1371-
boolean noDelay) throws IOException, UnknownHostException {
1381+
boolean noDelay, boolean isPooled) throws IOException, UnknownHostException {
13721382

13731383
super(bufferSize);
13741384

@@ -1378,7 +1388,10 @@ public TCPSockIO(SchoonerSockIOPool pool, String host, int bufferSize, int timeo
13781388
// get socket: default is to use non-blocking connect
13791389
sock = getSocket(ip[0], Integer.parseInt(ip[1]), connectTimeout);
13801390

1381-
writeBuf = ByteBuffer.allocateDirect(bufferSize);
1391+
if (isPooled)
1392+
writeBuf = ByteBuffer.allocateDirect(bufferSize);
1393+
else
1394+
writeBuf = ByteBuffer.allocate(bufferSize);
13821395

13831396
if (timeout >= 0)
13841397
this.sock.setSoTimeout(timeout);
@@ -1492,6 +1505,13 @@ public final void close() {
14921505
readBuf.clear();
14931506
if (isPooled)
14941507
sockets.add(this);
1508+
else {
1509+
try {
1510+
trueClose();
1511+
} catch (IOException e) {
1512+
log.error("++++ error closing socket: " + toString() + " for host: " + getHost());
1513+
}
1514+
}
14951515
}
14961516

14971517
/**

src/test/com/schooner/MemCached/OtherTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ public void testLogger() {
9898

9999
public void testUDPSockIO() {
100100
try {
101-
UDPSockIO io = new UDPSockIO(SchoonerSockIOPool.getInstance(), serverList[0], 1024 * 105, 100);
101+
UDPSockIO io = new UDPSockIO(SchoonerSockIOPool.getInstance(), serverList[0], 1024 * 105, 100, true);
102102
io.getHost();
103103
io.isAlive();
104104
io.write(null);
@@ -114,7 +114,7 @@ public void testUDPSockIO() {
114114
public void testTcpSockIO() {
115115
try {
116116
TCPSockIO io = new TCPSockIO(SchoonerSockIOPool.getInstance(), serverList[0], 1024 * 1025, 3000, 3000,
117-
false);
117+
false, true);
118118
io.isAlive();
119119
io.toString();
120120
io.readBytes(0);

0 commit comments

Comments
 (0)