Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion components/webui/client/public/settings.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"ClpStorageEngine": "clp",
"ClpQueryEngine": "native",
"ClpQueryEngine": "presto",
"MongoDbSearchResultsMetadataCollectionName": "results-metadata",
"SqlDbClpArchivesTableName": "clp_archives",
"SqlDbClpDatasetsTableName": "clp_datasets",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import {useCallback} from "react";

import {CaretRightOutlined} from "@ant-design/icons";
import {
Button,
Tooltip,
} from "antd";

import useSearchStore from "../../../SearchState/index";
import {handlePrestoQuerySubmit} from "../presto-search-requests";


/**
Expand All @@ -20,6 +23,10 @@ const RunButton = () => {
"Enter SQL query to run" :
"";

const handleClick = useCallback(() => {
handlePrestoQuerySubmit({queryString});
}, [queryString]);

return (
<Tooltip title={tooltipTitle}>
<Button
Expand All @@ -28,6 +35,7 @@ const RunButton = () => {
icon={<CaretRightOutlined/>}
size={"large"}
variant={"solid"}
onClick={handleClick}
>
Run
</Button>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import {submitQuery} from "../../../../api/presto-search";
import type {PrestoQueryJobCreationSchema} from "../../../../api/presto-search";

/**
* Submits a new Presto query to server.
*
* @param payload
*/
const handlePrestoQuerySubmit = (payload: PrestoQueryJobCreationSchema) => {
submitQuery(payload)
.then((result) => {
const {searchJobId} = result.data;
console.debug(
"Presto search job created - ",
"Search job ID:",
searchJobId
);
})
.catch((err: unknown) => {
console.error("Failed to submit query:", err);
});
};

export {
handlePrestoQuerySubmit,
};
38 changes: 38 additions & 0 deletions components/webui/server/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion components/webui/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@
"@aws-sdk/s3-request-presigner": "^3.758.0",
"@fastify/autoload": "^6.3.0",
"@fastify/env": "^5.0.2",
"@fastify/http-proxy": "^11.3.0",
"@fastify/mongodb": "^9.0.2",
"@fastify/mysql": "^5.0.2",
"@fastify/rate-limit": "^10.2.2",
"@fastify/http-proxy": "^11.3.0",
"@fastify/sensible": "^6.0.3",
"@fastify/static": "^8.1.1",
"@fastify/type-provider-typebox": "^5.1.0",
Expand All @@ -38,10 +38,12 @@
"fastify-plugin": "^5.0.1",
"http-status-codes": "^2.3.0",
"pino-pretty": "^13.0.0",
"presto-client": "^1.1.0",
"socket.io": "^4.8.1",
"typescript": "~5.7.3"
},
"devDependencies": {
"@types/presto-client": "^1.0.2",
"concurrently": "^9.1.2",
"eslint-config-yscope": "latest",
"fastify-cli": "^7.4.0",
Expand Down
6 changes: 5 additions & 1 deletion components/webui/server/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,9 @@
"StreamTargetUncompressedSize": 134217728,
"StreamFilesS3Region": null,
"StreamFilesS3PathPrefix": null,
"StreamFilesS3Profile": null
"StreamFilesS3Profile": null,

"ClpQueryEngine": "presto",
"PrestoHost": "localhost",
"PrestoPort": 8080
}
47 changes: 47 additions & 0 deletions components/webui/server/src/plugins/app/Presto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import fp from "fastify-plugin";
import {
Client,
ClientOptions,
} from "presto-client";

import settings from "../../../settings.json" with {type: "json"};


/**
* Class to manage Presto client connections.
*/
class Presto {
readonly client;

/**
* @param clientOptions
*/
constructor (clientOptions: ClientOptions) {
this.client = new Client(clientOptions);
}
}

declare module "fastify" {
interface FastifyInstance {
Presto?: Presto;
}
}

export default fp(
(fastify) => {
if ("presto" !== settings.ClpQueryEngine) {
return;
}

const clientOptions: ClientOptions = {
host: settings.PrestoHost,
port: settings.PrestoPort,
};

fastify.log.info(
clientOptions,
"Initializing Presto"
);
fastify.decorate("Presto", new Presto(clientOptions));
},
);
91 changes: 91 additions & 0 deletions components/webui/server/src/routes/api/presto-search/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import {FastifyPluginAsyncTypebox} from "@fastify/type-provider-typebox";
import {StatusCodes} from "http-status-codes";

import {ErrorSchema} from "../../../schemas/error.js";
import {
PrestoQueryJobCreationSchema,
PrestoQueryJobSchema,
} from "../../../schemas/presto-search.js";


/**
* Presto search API routes.
*
* @param fastify
*/
const plugin: FastifyPluginAsyncTypebox = async (fastify) => {
const {Presto} = fastify;

if ("undefined" === typeof Presto) {
throw new Error("Presto not available");
}

/**
* Submits a search query and initiates the search process.
*/
fastify.post(
"/query",
{
schema: {
body: PrestoQueryJobCreationSchema,
response: {
[StatusCodes.CREATED]: PrestoQueryJobSchema,
[StatusCodes.INTERNAL_SERVER_ERROR]: ErrorSchema,
},
tags: ["Presto Search"],
},
},

async (request, reply) => {
const {queryString} = request.body;

let searchJobId: string;

try {
searchJobId = await new Promise<string>((resolve, reject) => {
let isResolved = false;

Presto.client.execute({
// eslint-disable-next-line no-warning-comments
// TODO: Data, error, and success handlers are dummy implementations
// and should be completed.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Remove outdated TODO comment.

The TODO comment about dummy implementations should be removed since the handlers are now properly implemented.

-                        // eslint-disable-next-line no-warning-comments
-                        // TODO: Data, error, and success handlers are dummy implementations
-                        // and should be completed.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// eslint-disable-next-line no-warning-comments
// TODO: Data, error, and success handlers are dummy implementations
// and should be completed.
request.log.info({
error: error,
searchJobId: newSearchJobId,
state: stats.state,
}, "Presto search state updated");
success: () => {
request.log.info("Presto search succeeded");
resolve(searchJobId);
},
🤖 Prompt for AI Agents
In components/webui/server/src/routes/api/presto-search/index.ts around lines 49
to 51, remove the outdated TODO comment that states the data, error, and success
handlers are dummy implementations, as these handlers have now been properly
implemented and the comment is no longer relevant.

data: (_, data, columns) => {
request.log.info({columns, data}, "Presto data");
},
error: (error) => {
request.log.info(error, "Presto search failed");
if (false === isResolved) {
isResolved = true;
reject(new Error("Presto search failed"));
}
},
query: queryString,
state: (_, queryId, stats) => {
request.log.info({
searchJobId: queryId,
state: stats.state,
}, "Presto search state updated");

if (false === isResolved) {
isResolved = true;
resolve(queryId);
}
},
success: () => {
request.log.info("Presto search succeeded");
},
});
});
} catch (error) {
request.log.error(error, "Failed to submit Presto query");
throw error;
}

reply.code(StatusCodes.CREATED);

return {searchJobId};
}
);
};

export default plugin;
23 changes: 23 additions & 0 deletions components/webui/server/src/schemas/presto-search.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import {Type} from "@sinclair/typebox";

import {StringSchema} from "./common.js";


/**
* Schema for request to create a new Presto query job.
*/
const PrestoQueryJobCreationSchema = Type.Object({
queryString: StringSchema,
});

/**
* Schema to identify a Presto query job.
*/
const PrestoQueryJobSchema = Type.Object({
searchJobId: StringSchema,
});

export {
PrestoQueryJobCreationSchema,
PrestoQueryJobSchema,
};
Loading