Skip to content

Commit 75be9b7

Browse files
committed
Use lightweight /status endpoint for SEA heartbeat instead of full GetStatement
Changed checkStatementAlive from GET /sql/statements/{id} (~21KB response with full manifest/result data) to GET /sql/statements/{id}/status (~100 bytes with just state/error/sqlState). Reduces heartbeat bandwidth by ~99% per tick. Co-authored-by: Isaac Signed-off-by: Gopal Lal <gopal.lal@databricks.com>
1 parent fd4e90a commit 75be9b7

3 files changed

Lines changed: 14 additions & 28 deletions

File tree

src/main/java/com/databricks/jdbc/dbclient/impl/sqlexec/DatabricksSdkClient.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import com.databricks.jdbc.model.core.ExternalLink;
3838
import com.databricks.jdbc.model.core.ResultData;
3939
import com.databricks.jdbc.model.core.ResultManifest;
40+
import com.databricks.jdbc.model.core.StatementStatus;
4041
import com.databricks.jdbc.model.telemetry.enums.DatabricksDriverErrorCode;
4142
import com.databricks.sdk.WorkspaceClient;
4243
import com.databricks.sdk.core.ApiClient;
@@ -417,13 +418,13 @@ public DatabricksResultSet executeStatementAsync(
417418
@Override
418419
public boolean checkStatementAlive(StatementId typedStatementId) throws SQLException {
419420
String statementId = typedStatementId.toSQLExecStatementId();
420-
String getStatusPath = String.format(STATEMENT_PATH_WITH_ID, statementId);
421+
// Use lightweight /status endpoint (~100 bytes) instead of full GetStatement (~21KB)
422+
String statusPath = String.format(STATEMENT_STATUS_PATH_WITH_ID, statementId);
421423
try {
422-
GetStatementRequest request = new GetStatementRequest().setStatementId(statementId);
423-
Request req = new Request(Request.GET, getStatusPath, apiClient.serialize(request));
424-
req.withHeaders(getHeaders("getStatement"));
425-
GetStatementResponse response = apiClient.execute(req, GetStatementResponse.class);
426-
StatementState state = response.getStatus().getState();
424+
Request req = new Request(Request.GET, statusPath, (String) null);
425+
req.withHeaders(getHeaders("getStatementStatus"));
426+
StatementStatus status = apiClient.execute(req, StatementStatus.class);
427+
StatementState state = status.getState();
427428
// Terminal states mean the operation is no longer alive
428429
return state != StatementState.CANCELED
429430
&& state != StatementState.CLOSED

src/main/java/com/databricks/jdbc/dbclient/impl/sqlexec/PathConstants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ public class PathConstants {
88
public static final String STATEMENT_PATH = BASE_PATH + "statements/";
99
public static final String STATEMENT_PATH_WITH_ID = STATEMENT_PATH + "%s";
1010
public static final String CANCEL_STATEMENT_PATH_WITH_ID = STATEMENT_PATH + "%s/cancel";
11+
public static final String STATEMENT_STATUS_PATH_WITH_ID = STATEMENT_PATH + "%s/status";
1112
public static final String RESULT_CHUNK_PATH = STATEMENT_PATH_WITH_ID + "/result/chunks/%s";
1213
public static final String TELEMETRY_PATH = "/telemetry-ext";
1314
public static final String TELEMETRY_PATH_UNAUTHENTICATED = "/telemetry-unauth";

src/test/java/com/databricks/jdbc/dbclient/impl/sqlexec/DatabricksSdkClientTest.java

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1324,12 +1324,8 @@ public void testCheckStatementAlive_succeededState_returnsTrue() throws Exceptio
13241324
new DatabricksSdkClient(connectionContext, statementExecutionService, apiClient);
13251325

13261326
StatementStatus status = new StatementStatus().setState(StatementState.SUCCEEDED);
1327-
GetStatementResponse response = new GetStatementResponse();
1328-
response.setStatus(status);
1329-
response.setStatementId(STATEMENT_ID.toSQLExecStatementId());
13301327

1331-
when(apiClient.execute(any(Request.class), eq(GetStatementResponse.class)))
1332-
.thenReturn(response);
1328+
when(apiClient.execute(any(Request.class), eq(StatementStatus.class))).thenReturn(status);
13331329

13341330
assertTrue(databricksSdkClient.checkStatementAlive(STATEMENT_ID));
13351331
}
@@ -1342,11 +1338,8 @@ public void testCheckStatementAlive_runningState_returnsTrue() throws Exception
13421338
new DatabricksSdkClient(connectionContext, statementExecutionService, apiClient);
13431339

13441340
StatementStatus status = new StatementStatus().setState(StatementState.RUNNING);
1345-
GetStatementResponse response = new GetStatementResponse();
1346-
response.setStatus(status);
13471341

1348-
when(apiClient.execute(any(Request.class), eq(GetStatementResponse.class)))
1349-
.thenReturn(response);
1342+
when(apiClient.execute(any(Request.class), eq(StatementStatus.class))).thenReturn(status);
13501343

13511344
assertTrue(databricksSdkClient.checkStatementAlive(STATEMENT_ID));
13521345
}
@@ -1359,11 +1352,8 @@ public void testCheckStatementAlive_canceledState_returnsFalse() throws Exceptio
13591352
new DatabricksSdkClient(connectionContext, statementExecutionService, apiClient);
13601353

13611354
StatementStatus status = new StatementStatus().setState(StatementState.CANCELED);
1362-
GetStatementResponse response = new GetStatementResponse();
1363-
response.setStatus(status);
13641355

1365-
when(apiClient.execute(any(Request.class), eq(GetStatementResponse.class)))
1366-
.thenReturn(response);
1356+
when(apiClient.execute(any(Request.class), eq(StatementStatus.class))).thenReturn(status);
13671357

13681358
assertFalse(databricksSdkClient.checkStatementAlive(STATEMENT_ID));
13691359
}
@@ -1376,11 +1366,8 @@ public void testCheckStatementAlive_closedState_returnsFalse() throws Exception
13761366
new DatabricksSdkClient(connectionContext, statementExecutionService, apiClient);
13771367

13781368
StatementStatus status = new StatementStatus().setState(StatementState.CLOSED);
1379-
GetStatementResponse response = new GetStatementResponse();
1380-
response.setStatus(status);
13811369

1382-
when(apiClient.execute(any(Request.class), eq(GetStatementResponse.class)))
1383-
.thenReturn(response);
1370+
when(apiClient.execute(any(Request.class), eq(StatementStatus.class))).thenReturn(status);
13841371

13851372
assertFalse(databricksSdkClient.checkStatementAlive(STATEMENT_ID));
13861373
}
@@ -1393,11 +1380,8 @@ public void testCheckStatementAlive_failedState_returnsFalse() throws Exception
13931380
new DatabricksSdkClient(connectionContext, statementExecutionService, apiClient);
13941381

13951382
StatementStatus status = new StatementStatus().setState(StatementState.FAILED);
1396-
GetStatementResponse response = new GetStatementResponse();
1397-
response.setStatus(status);
13981383

1399-
when(apiClient.execute(any(Request.class), eq(GetStatementResponse.class)))
1400-
.thenReturn(response);
1384+
when(apiClient.execute(any(Request.class), eq(StatementStatus.class))).thenReturn(status);
14011385

14021386
assertFalse(databricksSdkClient.checkStatementAlive(STATEMENT_ID));
14031387
}
@@ -1409,7 +1393,7 @@ public void testCheckStatementAlive_exceptionWrapped() throws Exception {
14091393
DatabricksSdkClient databricksSdkClient =
14101394
new DatabricksSdkClient(connectionContext, statementExecutionService, apiClient);
14111395

1412-
when(apiClient.execute(any(Request.class), eq(GetStatementResponse.class)))
1396+
when(apiClient.execute(any(Request.class), eq(StatementStatus.class)))
14131397
.thenThrow(new RuntimeException("Network error"));
14141398

14151399
DatabricksSQLException exception =

0 commit comments

Comments
 (0)