Skip to content

Commit 912698b

Browse files
authored
Fix #1256 Socket Mode connection error issue (#1265)
1 parent 4d82e6b commit 912698b

File tree

3 files changed

+58
-5
lines changed

3 files changed

+58
-5
lines changed

slack-api-client/src/main/java/com/slack/api/socket_mode/SocketModeClient.java

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,14 @@ enum Backend {
5757
*/
5858
boolean verifyConnection();
5959

60+
/**
61+
* Returns true if the client tries to reconnect when onClose listeners are called
62+
* plus isAutoReconnectEnabled() is true. Default: false
63+
*/
64+
boolean isAutoReconnectOnCloseEnabled();
65+
66+
void setAutoReconnectOnCloseEnabled(boolean autoReconnectOnCloseEnabled);
67+
6068
/**
6169
* Connects to a new WSS endpoint and starts a new WebSocket session.
6270
*/
@@ -256,11 +264,30 @@ default void runCloseListenersAndAutoReconnectAsNecessary(Integer code, String r
256264
for (WebSocketCloseListener listener : getWebSocketCloseListeners()) {
257265
listener.handle(code, reason);
258266
}
259-
if (isAutoReconnectEnabled() && !verifyConnection()) {
260-
try {
261-
connectToNewEndpoint();
262-
} catch (IOException e) {
263-
getLogger().error("Failed to reconnect to the Socket Mode server: {}", e.getMessage(), e);
267+
if (isAutoReconnectOnCloseEnabled()) {
268+
// Starting in December 2023, the Socket Mode server changed its behavior.
269+
// As a result, the logic here can result in a rate-limited error.
270+
//
271+
// Reported issues:
272+
// * https://github.com/slackapi/java-slack-sdk/issues/1256
273+
// * https://github.com/slackapi/java-slack-sdk/issues/1223
274+
//
275+
// Originally, this logic was added to let this client get back online even more quickly when something is wrong.
276+
// However, it seems that the logic has been relying on the server's past behavior characteristics.
277+
// Note that, even when the underlying connection is closed due to "reason: Closed abnormally." or similar,
278+
// the session monitor under the hood continues to try to reconnect for you.
279+
// For this reason, disabling this logic should be safe for any situations.
280+
// If there is an exception this assumption does not cover, we may need to improve the logic to ensure better stability.
281+
//
282+
// Therefore, in v1.37.0, this SDK disabled this by default.
283+
// If you want to turn it on again, set the isAutoReconnectOnCloseEnabled to true.
284+
285+
if (isAutoReconnectEnabled() && !verifyConnection()) {
286+
try {
287+
connectToNewEndpoint();
288+
} catch (IOException e) {
289+
getLogger().error("Failed to reconnect to the Socket Mode server: {}", e.getMessage(), e);
290+
}
264291
}
265292
}
266293
}

slack-api-client/src/main/java/com/slack/api/socket_mode/impl/SocketModeClientJavaWSImpl.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public class SocketModeClientJavaWSImpl implements SocketModeClient {
4141
private final Gson gson;
4242
private URI wssUri;
4343
private boolean autoReconnectEnabled;
44+
private boolean autoReconnectOnCloseEnabled;
4445
private SocketModeMessageQueue messageQueue;
4546
private ScheduledExecutorService messageProcessorExecutor;
4647
private boolean sessionMonitorEnabled;
@@ -110,6 +111,8 @@ public SocketModeClientJavaWSImpl(
110111

111112
setMessageQueue(messageQueue);
112113
setAutoReconnectEnabled(autoReconnectEnabled);
114+
// You can use the setter method if you set the value to true
115+
setAutoReconnectOnCloseEnabled(false);
113116
setSessionMonitorEnabled(sessionMonitorEnabled);
114117
initializeSessionMonitorExecutor(sessionMonitorIntervalMillis);
115118
initializeMessageProcessorExecutor(concurrency);
@@ -156,6 +159,16 @@ public boolean verifyConnection() {
156159
return false;
157160
}
158161

162+
@Override
163+
public boolean isAutoReconnectOnCloseEnabled() {
164+
return this.autoReconnectOnCloseEnabled;
165+
}
166+
167+
@Override
168+
public void setAutoReconnectOnCloseEnabled(boolean autoReconnectOnCloseEnabled) {
169+
this.autoReconnectOnCloseEnabled = autoReconnectOnCloseEnabled;
170+
}
171+
159172
@Override
160173
public void disconnect() {
161174
setAutoReconnectEnabled(false);

slack-api-client/src/main/java/com/slack/api/socket_mode/impl/SocketModeClientTyrusImpl.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ public class SocketModeClientTyrusImpl implements SocketModeClient {
4343
private final Gson gson;
4444
private URI wssUri;
4545
private boolean autoReconnectEnabled;
46+
private boolean autoReconnectOnCloseEnabled;
4647
private SocketModeMessageQueue messageQueue;
4748
private ScheduledExecutorService messageProcessorExecutor;
4849
private boolean sessionMonitorEnabled;
@@ -121,6 +122,8 @@ public SocketModeClientTyrusImpl(
121122

122123
setMessageQueue(messageQueue);
123124
setAutoReconnectEnabled(autoReconnectEnabled);
125+
// You can use the setter method if you set the value to true
126+
setAutoReconnectOnCloseEnabled(false);
124127
setSessionMonitorEnabled(sessionMonitorEnabled);
125128
initializeSessionMonitorExecutor(sessionMonitorIntervalMillis);
126129
initializeMessageProcessorExecutor(concurrency);
@@ -217,6 +220,16 @@ public boolean verifyConnection() {
217220
return false;
218221
}
219222

223+
@Override
224+
public boolean isAutoReconnectOnCloseEnabled() {
225+
return this.autoReconnectOnCloseEnabled;
226+
}
227+
228+
@Override
229+
public void setAutoReconnectOnCloseEnabled(boolean autoReconnectOnCloseEnabled) {
230+
this.autoReconnectOnCloseEnabled = autoReconnectOnCloseEnabled;
231+
}
232+
220233
@Override
221234
public void disconnect() throws IOException {
222235
setAutoReconnectEnabled(false);

0 commit comments

Comments
 (0)