Skip to content

Commit e499a52

Browse files
authored
minor: Show running Dart queries first. (#19237)
This patch adjusts the ordering of current-dart-panel in the web console to match the current tasks panel: RUNNING is first, ACCEPTED is next, then all the completed states follow. Within each category, queries are sorted by timestamp, newest first: RUNNING and ACCEPTED by start time, and completed queries by finish time. This patch also renames the interface method "getRunningQueries" to "getQueries", because it can return completed queries too.
1 parent 4a49c73 commit e499a52

11 files changed

Lines changed: 47 additions & 21 deletions

File tree

multi-stage-query/src/main/java/org/apache/druid/msq/dart/controller/sql/DartSqlClient.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,15 @@
3232
public interface DartSqlClient
3333
{
3434
/**
35-
* Get information about all currently-running queries on this server.
35+
* Get information about all currently-running, and possibly also recently-completed, queries on this server.
3636
*
3737
* @param selfOnly true if only queries from this server should be returned; false if queries from all servers
3838
* should be returned
3939
* @param includeComplete true if completed queries should be included in the response
4040
*
4141
* @see SqlResource#doGetRunningQueries(String, String, HttpServletRequest) the server side
4242
*/
43-
ListenableFuture<GetQueriesResponse> getRunningQueries(boolean selfOnly, boolean includeComplete);
43+
ListenableFuture<GetQueriesResponse> getQueries(boolean selfOnly, boolean includeComplete);
4444

4545
/**
4646
* Get query report for a particular SQL query ID on this server.

multi-stage-query/src/main/java/org/apache/druid/msq/dart/controller/sql/DartSqlClientImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public DartSqlClientImpl(final ServiceClient client, final ObjectMapper jsonMapp
4949
}
5050

5151
@Override
52-
public ListenableFuture<GetQueriesResponse> getRunningQueries(final boolean selfOnly, final boolean includeComplete)
52+
public ListenableFuture<GetQueriesResponse> getQueries(final boolean selfOnly, final boolean includeComplete)
5353
{
5454
try {
5555
URIBuilder builder = new URIBuilder("/queries");

multi-stage-query/src/main/java/org/apache/druid/msq/dart/controller/sql/DartSqlEngine.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ public class DartSqlEngine implements SqlEngine
8282
{
8383
public static final String NAME = "msq-dart";
8484
private static final Logger log = new Logger(DartSqlEngine.class);
85-
8685
private final DartControllerContextFactory controllerContextFactory;
8786
private final DartControllerRegistry controllerRegistry;
8887
private final DartControllerConfig controllerConfig;
@@ -256,7 +255,7 @@ public SqlStatementFactory getSqlStatementFactory()
256255
}
257256

258257
@Override
259-
public GetQueriesResponse getRunningQueries(
258+
public GetQueriesResponse getQueries(
260259
boolean selfOnly,
261260
boolean includeComplete,
262261
AuthenticationResult authenticationResult,
@@ -276,7 +275,7 @@ public GetQueriesResponse getRunningQueries(
276275
Futures.successfulAsList(
277276
Iterables.transform(
278277
sqlClients.getAllClients(),
279-
client -> client.getRunningQueries(true, includeComplete)
278+
client -> client.getQueries(true, includeComplete)
280279
)
281280
),
282281
true

multi-stage-query/src/test/java/org/apache/druid/msq/dart/controller/http/DartSqlResourceTest.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ public void test_getRunningQueries_global_superUser()
384384
StandardQueryState.RUNNING,
385385
null
386386
);
387-
Mockito.when(dartSqlClient.getRunningQueries(true, false))
387+
Mockito.when(dartSqlClient.getQueries(true, false))
388388
.thenReturn(Futures.immediateFuture(new GetQueriesResponse(Collections.singletonList(remoteQueryInfo))));
389389

390390
// With selfOnly = null, the endpoint returns both queries.
@@ -415,7 +415,7 @@ public void test_getRunningQueries_global_remoteError_superUser()
415415
final ControllerHolder localHolder = setUpMockRunningQuery(REGULAR_USER_NAME);
416416

417417
// Remote call fails.
418-
Mockito.when(dartSqlClient.getRunningQueries(true, false))
418+
Mockito.when(dartSqlClient.getQueries(true, false))
419419
.thenReturn(Futures.immediateFailedFuture(new IOException("something went wrong")));
420420

421421
// We only see local queries, because the remote call failed. (The entire call doesn't fail; we see what we
@@ -453,7 +453,7 @@ public void test_getRunningQueries_global_regularUser()
453453
StandardQueryState.RUNNING,
454454
null
455455
);
456-
Mockito.when(dartSqlClient.getRunningQueries(true, false))
456+
Mockito.when(dartSqlClient.getQueries(true, false))
457457
.thenReturn(Futures.immediateFuture(new GetQueriesResponse(Collections.singletonList(remoteQueryInfo))));
458458

459459
// The endpoint returns only the query issued by REGULAR_USER_NAME.
@@ -491,7 +491,7 @@ public void test_getRunningQueries_global_differentRegularUser()
491491
StandardQueryState.RUNNING,
492492
null
493493
);
494-
Mockito.when(dartSqlClient.getRunningQueries(true, false))
494+
Mockito.when(dartSqlClient.getQueries(true, false))
495495
.thenReturn(Futures.immediateFuture(new GetQueriesResponse(Collections.singletonList(remoteQueryInfo))));
496496

497497
// The endpoint returns only the query issued by DIFFERENT_REGULAR_USER_NAME.

multi-stage-query/src/test/java/org/apache/druid/msq/dart/controller/sql/DartSqlClientImplTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ public void test_getMessages_all() throws Exception
8787
jsonMapper.writeValueAsBytes(getQueriesResponse)
8888
);
8989

90-
final ListenableFuture<GetQueriesResponse> result = dartSqlClient.getRunningQueries(false, false);
90+
final ListenableFuture<GetQueriesResponse> result = dartSqlClient.getQueries(false, false);
9191
Assertions.assertEquals(getQueriesResponse, result.get());
9292
}
9393

@@ -117,7 +117,7 @@ public void test_getMessages_selfOnly() throws Exception
117117
jsonMapper.writeValueAsBytes(getQueriesResponse)
118118
);
119119

120-
final ListenableFuture<GetQueriesResponse> result = dartSqlClient.getRunningQueries(true, false);
120+
final ListenableFuture<GetQueriesResponse> result = dartSqlClient.getQueries(true, false);
121121
Assertions.assertEquals(getQueriesResponse, result.get());
122122
}
123123

@@ -147,7 +147,7 @@ public void test_getMessages_includeComplete() throws Exception
147147
jsonMapper.writeValueAsBytes(getQueriesResponse)
148148
);
149149

150-
final ListenableFuture<GetQueriesResponse> result = dartSqlClient.getRunningQueries(false, true);
150+
final ListenableFuture<GetQueriesResponse> result = dartSqlClient.getQueries(false, true);
151151
Assertions.assertEquals(getQueriesResponse, result.get());
152152
}
153153
}

sql/src/main/java/org/apache/druid/sql/calcite/run/SqlEngine.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ default void initContextMap(Map<String, Object> contextMap)
144144
* @param stateReadAuthorization authorization for the STATE READ resource. If this is authorized, implementations
145145
* should allow all queries to be visible
146146
*/
147-
default GetQueriesResponse getRunningQueries(
147+
default GetQueriesResponse getQueries(
148148
boolean selfOnly,
149149
boolean includeComplete,
150150
AuthenticationResult authenticationResult,

sql/src/main/java/org/apache/druid/sql/calcite/schema/SystemSchema.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1282,7 +1282,7 @@ public Enumerable<Object[]> scan(
12821282
// Get queries from all engines
12831283
final List<QueryInfo> allQueries = new ArrayList<>();
12841284
for (final SqlEngine sqlEngine : sqlEngineRegistryProvider.get().getAllEngines()) {
1285-
final GetQueriesResponse response = sqlEngine.getRunningQueries(
1285+
final GetQueriesResponse response = sqlEngine.getQueries(
12861286
false, // selfOnly false to get queries from all servers
12871287
true, // includeComplete true to include all queries
12881288
authenticationResult,

sql/src/main/java/org/apache/druid/sql/http/SqlResource.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ public Response doGetRunningQueries(
168168
// Get running queries from all engines that support it.
169169
for (SqlEngine sqlEngine : engines) {
170170
queries.addAll(
171-
sqlEngine.getRunningQueries(
171+
sqlEngine.getQueries(
172172
selfOnly != null,
173173
includeComplete != null,
174174
authenticationResult,

sql/src/test/java/org/apache/druid/sql/calcite/schema/SystemSchemaTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1665,7 +1665,7 @@ public void testQueriesTable()
16651665
// Create mock SqlEngine that returns test queries
16661666
final SqlEngine mockEngine = EasyMock.createMock(SqlEngine.class);
16671667
EasyMock.expect(mockEngine.name()).andReturn("native").anyTimes();
1668-
EasyMock.expect(mockEngine.getRunningQueries(
1668+
EasyMock.expect(mockEngine.getQueries(
16691669
EasyMock.eq(false),
16701670
EasyMock.eq(true),
16711671
EasyMock.anyObject(),

web-console/src/druid-models/dart/dart-query-entry.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,30 @@ export interface DartQueryEntry {
2525
identity: string;
2626
startTime: string;
2727
state: 'ACCEPTED' | 'RUNNING' | 'CANCELED' | 'SUCCESS' | 'FAILED';
28+
durationMs?: number;
29+
}
30+
31+
const STATE_RANK: Record<string, number> = {
32+
RUNNING: 2,
33+
ACCEPTED: 1,
34+
};
35+
36+
export function compareForDisplay(a: DartQueryEntry, b: DartQueryEntry): number {
37+
const stateA = STATE_RANK[a.state] ?? 0;
38+
const stateB = STATE_RANK[b.state] ?? 0;
39+
40+
// Primary: RUNNING > ACCEPTED > others
41+
if (stateA !== stateB) {
42+
return stateB - stateA;
43+
}
44+
45+
if (stateA > 0) {
46+
// RUNNING or ACCEPTED: descending startTime (newest first)
47+
return b.startTime.localeCompare(a.startTime);
48+
} else {
49+
// Finished: descending finish time (startTime + durationMs)
50+
const finishA = new Date(a.startTime).valueOf() + (a.durationMs ?? 0);
51+
const finishB = new Date(b.startTime).valueOf() + (b.durationMs ?? 0);
52+
return finishB - finishA;
53+
}
2854
}

0 commit comments

Comments
 (0)