Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
fix: add a socket timeout on cancel requests
The timeout is configurable through cancelSignalTimeout in seconds with defult value of 10 seconds
fixes #603
- Loading branch information
|
@@ -250,6 +250,14 @@ |
|
|
*/ |
|
|
SOCKET_TIMEOUT("socketTimeout", "0", "The timeout value used for socket read operations."), |
|
|
|
|
|
/** |
|
|
* Cancel command is sent out of band over its own connection, so cancel message can itself get |
|
|
* stuck. |
|
|
* This property controls "connect timeout" and "socket timeout" used for cancel commands. |
|
|
* The timeout is specified in seconds. Default value is 10 seconds. |
|
|
*/ |
|
|
CANCEL_SIGNAL_TIMEOUT("cancelSignalTimeout", "10", "The timeout that is used for sending cancel command."), |
|
|
|
|
|
/** |
|
|
* Socket factory used to create socket. A null value, which is the default, means system default. |
|
|
*/ |
|
|
|
@@ -132,9 +132,12 @@ public ProtocolConnection openConnectionImpl(HostSpec[] hostSpecs, String user, |
|
|
// Do authentication (until AuthenticationOk). |
|
|
doAuthentication(newStream, user, PGProperty.PASSWORD.get(info), logger); |
|
|
|
|
|
int cancelSignalTimeout = PGProperty.CANCEL_SIGNAL_TIMEOUT.getInt(info) * 1000; |
|
|
|
|
|
// Do final startup. |
|
|
ProtocolConnectionImpl protoConnection = |
|
|
new ProtocolConnectionImpl(newStream, user, database, logger, connectTimeout); |
|
|
new ProtocolConnectionImpl(newStream, user, database, logger, |
|
|
cancelSignalTimeout); |
|
|
readStartupMessages(newStream, protoConnection, logger); |
|
|
|
|
|
// Check Master or Slave |
|
|
|
@@ -32,13 +32,13 @@ |
|
|
*/ |
|
|
class ProtocolConnectionImpl implements ProtocolConnection { |
|
|
ProtocolConnectionImpl(PGStream pgStream, String user, String database, Logger logger, |
|
|
int connectTimeout) { |
|
|
int cancelSignalTimeout) { |
|
|
this.pgStream = pgStream; |
|
|
this.user = user; |
|
|
this.database = database; |
|
|
this.logger = logger; |
|
|
this.executor = new QueryExecutorImpl(this, pgStream, logger); |
|
|
this.connectTimeout = connectTimeout; |
|
|
this.cancelSignalTimeout = cancelSignalTimeout; |
|
|
} |
|
|
|
|
|
public HostSpec getHostSpec() { |
|
@@ -102,7 +102,10 @@ public void sendQueryCancel() throws SQLException { |
|
|
} |
|
|
|
|
|
cancelStream = |
|
|
new PGStream(pgStream.getSocketFactory(), pgStream.getHostSpec(), connectTimeout); |
|
|
new PGStream(pgStream.getSocketFactory(), pgStream.getHostSpec(), cancelSignalTimeout); |
|
|
if (cancelSignalTimeout > 0) { |
|
|
cancelStream.getSocket().setSoTimeout(cancelSignalTimeout); |
|
|
} |
|
|
cancelStream.SendInteger4(16); |
|
|
cancelStream.SendInteger2(1234); |
|
|
cancelStream.SendInteger2(5678); |
|
@@ -255,6 +258,5 @@ public String getApplicationName() { |
|
|
private final String database; |
|
|
private final QueryExecutorImpl executor; |
|
|
private final Logger logger; |
|
|
|
|
|
private final int connectTimeout; |
|
|
private final int cancelSignalTimeout; |
|
|
} |
|
@@ -222,9 +222,12 @@ public ProtocolConnection openConnectionImpl(HostSpec[] hostSpecs, String user, |
|
|
// Do authentication (until AuthenticationOk). |
|
|
doAuthentication(newStream, hostSpec.getHost(), user, info, logger); |
|
|
|
|
|
int cancelSignalTimeout = PGProperty.CANCEL_SIGNAL_TIMEOUT.getInt(info) * 1000; |
|
|
|
|
|
// Do final startup. |
|
|
ProtocolConnectionImpl protoConnection = |
|
|
new ProtocolConnectionImpl(newStream, user, database, info, logger, connectTimeout); |
|
|
new ProtocolConnectionImpl(newStream, user, database, info, logger, |
|
|
cancelSignalTimeout); |
|
|
readStartupMessages(newStream, protoConnection, logger); |
|
|
|
|
|
// Check Master or Slave |
|
|
|
@@ -35,15 +35,15 @@ |
|
|
*/ |
|
|
class ProtocolConnectionImpl implements ProtocolConnection { |
|
|
ProtocolConnectionImpl(PGStream pgStream, String user, String database, Properties info, |
|
|
Logger logger, int connectTimeout) { |
|
|
Logger logger, int cancelSignalTimeout) { |
|
|
this.pgStream = pgStream; |
|
|
this.user = user; |
|
|
this.database = database; |
|
|
this.logger = logger; |
|
|
this.executor = new QueryExecutorImpl(this, pgStream, info, logger); |
|
|
// default value for server versions that don't report standard_conforming_strings |
|
|
this.standardConformingStrings = false; |
|
|
this.connectTimeout = connectTimeout; |
|
|
this.cancelSignalTimeout = cancelSignalTimeout; |
|
|
} |
|
|
|
|
|
public HostSpec getHostSpec() { |
|
@@ -103,7 +103,10 @@ public void sendQueryCancel() throws SQLException { |
|
|
} |
|
|
|
|
|
cancelStream = |
|
|
new PGStream(pgStream.getSocketFactory(), pgStream.getHostSpec(), connectTimeout); |
|
|
new PGStream(pgStream.getSocketFactory(), pgStream.getHostSpec(), cancelSignalTimeout); |
|
|
if (cancelSignalTimeout > 0) { |
|
|
cancelStream.getSocket().setSoTimeout(cancelSignalTimeout); |
|
|
} |
|
|
cancelStream.SendInteger4(16); |
|
|
cancelStream.SendInteger2(1234); |
|
|
cancelStream.SendInteger2(5678); |
|
@@ -282,8 +285,7 @@ public String getApplicationName() { |
|
|
private final String database; |
|
|
private final QueryExecutorImpl executor; |
|
|
private final Logger logger; |
|
|
|
|
|
private final int connectTimeout; |
|
|
private final int cancelSignalTimeout; |
|
|
|
|
|
/** |
|
|
* TimeZone of the current connection (TimeZone backend parameter) |
|
|
|
@@ -476,6 +476,22 @@ public int getSocketTimeout() { |
|
|
return PGProperty.SOCKET_TIMEOUT.getIntNoCheck(properties); |
|
|
} |
|
|
|
|
|
/** |
|
|
* @param seconds timeout that is used for sending cancel command |
|
|
* @see PGProperty#CANCEL_SIGNAL_TIMEOUT |
|
|
*/ |
|
|
public void setCancelSignalTimeout(int seconds) { |
|
|
PGProperty.CANCEL_SIGNAL_TIMEOUT.set(properties, seconds); |
|
|
} |
|
|
|
|
|
/** |
|
|
* @return timeout that is used for sending cancel command in seconds |
|
|
* @see PGProperty#CANCEL_SIGNAL_TIMEOUT |
|
|
*/ |
|
|
public int getCancelSignalTimeout() { |
|
|
return PGProperty.CANCEL_SIGNAL_TIMEOUT.getIntNoCheck(properties); |
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
* @param enabled if SSL is enabled |
|
|