Implementation:Apache Druid UseQueryManager
| Knowledge Sources | |
|---|---|
| Domains | Web_Console, Async_Data_Fetching |
| Last Updated | 2026-02-10 10:00 GMT |
Overview
useQueryManager is a custom React hook that wraps the QueryManager utility class, providing a declarative interface for managing asynchronous query lifecycle including loading, success, and error states.
Description
The hook creates and manages a QueryManager instance within a React component's lifecycle, handling initialization on mount and termination on unmount. It supports both imperative query execution (via the returned QueryManager instance) and declarative query triggering (via the query option that automatically reruns when changed). The hook is designed for compatibility with React 18's strict mode by detecting terminated managers and recreating them on remount. State changes from the QueryManager are propagated to the component via a ref-backed state pattern.
Usage
Used extensively throughout the Druid web console as the primary pattern for fetching data from Druid API endpoints, managing loading states, and handling errors in functional components.
Code Reference
Source Location
- Repository: Apache Druid
- File: web-console/src/hooks/use-query-manager.ts
- Lines: 1-89
Signature
export interface UseQueryManagerOptions<Q, R, I, E extends Error>
extends Omit<QueryManagerOptions<Q, R, I, E>, 'onStateChange'> {
query?: Q | undefined;
initQuery?: Q;
}
export function useQueryManager<Q, R, I = never, E extends Error = Error>(
options: UseQueryManagerOptions<Q, R, I, E>,
): [QueryState<R, E, I>, QueryManager<Q, R, I, E>];
Import
import { useQueryManager } from './hooks/use-query-manager';
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| processQuery | (query: Q, signal: AbortSignal) => Promise<R> | Yes | The async function that executes the query and returns the result |
| query | Q or undefined | No | A declarative query value; when changed, automatically triggers processQuery |
| initQuery | Q | No | A query to run immediately on mount |
| initState | QueryState<R, E, I> | No | The initial QueryState before any query runs (defaults to QueryState.INIT) |
| backgroundStatusCheck | function | No | An optional function for polling background task status |
Outputs
| Name | Type | Description |
|---|---|---|
| queryState | QueryState<R, E, I> | The current state of the query (loading, data, error, intermediate) |
| queryManager | QueryManager<Q, R, I, E> | The underlying QueryManager instance for imperative control (rerunLastQuery, runQuery, terminate) |
Usage Examples
Fetching datasource list
const [datasourcesState, queryManager] = useQueryManager<null, Datasource[]>({
processQuery: async (_, signal) => {
const resp = await Api.instance.get('/druid/coordinator/v1/datasources', { signal });
return resp.data;
},
initQuery: null,
});
if (datasourcesState.loading) return <Loader />;
if (datasourcesState.error) return <div>{datasourcesState.getErrorMessage()}</div>;
return <DatasourceTable datasources={datasourcesState.data} />;