Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add page for running queries #73

Merged
merged 7 commits into from
Jul 19, 2024
Merged

add page for running queries #73

merged 7 commits into from
Jul 19, 2024

Conversation

eriktaubeneck
Copy link
Member

@eriktaubeneck eriktaubeneck commented Jul 17, 2024

adds a page for running queries.

Summary by CodeRabbit

  • New Features

    • Introduced dynamic fetching and display of query data.
    • Added periodic data updates and real-time query status rendering.
    • Enabled conditional rendering based on query data availability.
  • Bug Fixes

    • Improved query status updates and rendering logic.
  • Improvements

    • Enhanced state management for query and status data.
    • Streamlined components to use unified status events for better clarity and performance.
  • API Changes

    • Added a new function to retrieve queries by UUID from the database.

Copy link

vercel bot commented Jul 17, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
draft ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jul 19, 2024 6:17am

Copy link
Contributor

coderabbitai bot commented Jul 17, 2024

Walkthrough

This update enhances the query handling functionality across multiple components in the project. It introduces dynamic client-side fetching and display of query data, state management for query status updates, and streamlined data handling mechanisms. A new function for fetching queries by UUID from the Supabase database is also included, significantly improving data retrieval capabilities while refining component interactions for better maintainability and clarity.

Changes

File Summary of Changes
server/app/query/page.tsx Added client-side fetching, state management for query data, and dynamic rendering for query statuses.
.../query/view/[id]/components.tsx Refactored RunTimePill to accept a consolidated statusEvent object, improving clarity and maintenance.
.../query/view/[id]/page.tsx Integrated state variables for status events and updated rendering logic to utilize statusEvent.
server/data/query.ts Introduced getQueryByUUID for retrieving queries by UUID from Supabase.
sidecar/app/routes/websockets.py Modified logging behavior in status_websocket to reduce debug output during query status updates.

Poem

In the whisper of code, a change so grand,
Queries fetch and render, by the user’s hand.
UUIDs now unlock the database gate,
Dynamic and swift, no longer do we wait.
Amidst the bytes and states, we celebrate,
A bunny’s work, in tech’s grand estate. 🐰✨


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@akoshelev
Copy link
Collaborator

can you show how it looks by pasting a screenshot of it?

@eriktaubeneck
Copy link
Member Author

image image

Base automatically changed from query-manager to main July 17, 2024 22:48
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 7490840 and 801548f.

Files selected for processing (10)
  • server/app/header.tsx (1 hunks)
  • server/app/page.tsx (1 hunks)
  • server/app/query/page.tsx (1 hunks)
  • server/app/query/servers.tsx (6 hunks)
  • server/app/query/view/[id]/components.tsx (3 hunks)
  • server/app/query/view/[id]/page.tsx (8 hunks)
  • server/data/query.ts (1 hunks)
  • sidecar/app/query/ipa.py (1 hunks)
  • sidecar/app/routes/start.py (2 hunks)
  • sidecar/tests/app/routes/test_start.py (2 hunks)
Additional context used
Biome
server/app/query/page.tsx

[error] 36-36: Do not access Object.prototype method 'hasOwnProperty' from target object.

It's recommended using Object.hasOwn() instead of using Object.hasOwnProperty().
See MDN web docs for more details.

(lint/suspicious/noPrototypeBuiltins)

Additional comments not posted (33)
server/data/query.ts (1)

58-78: LGTM!

The function implementation looks good and follows best practices for querying the database and processing the data.

server/app/page.tsx (1)

61-61: LGTM!

The link text change from "Dashboard" to "Queries" based on the user's login status is correct and improves clarity.

server/app/query/view/[id]/components.tsx (1)

Line range hint 67-90:
LGTM!

The refactoring of the RunTimePill component to accept a single statusEvent object simplifies the component's interface and enhances maintainability.

sidecar/app/routes/start.py (3)

28-29: LGTM!

The endpoint path change from /capacity_available to /capacity-available is correct and follows URL naming conventions.


36-37: LGTM!

The endpoint path change from /running_queries to /running-queries is correct and follows URL naming conventions.


112-118: LGTM!

The function renaming and return statement modification are correct and improve clarity and consistency.

sidecar/tests/app/routes/test_start.py (11)

37-39: LGTM!

The test function correctly verifies the /start/capacity-available endpoint.


44-46: LGTM!

The test function correctly verifies the /start/capacity-available endpoint when a query is running.


50-52: LGTM!

The test function correctly verifies the /start/running-queries endpoint.


Line range hint 57-70:
LGTM!

The test function correctly verifies the /start/ipa-helper/{query_id} endpoint.


Line range hint 75-86:
LGTM!

The test function correctly verifies that an IncorrectRoleError is raised for the /start/ipa-helper/{query_id} endpoint with a coordinator role.


Line range hint 91-104:
LGTM!

The test function correctly verifies the /start/ipa-query/{query_id} endpoint.


Line range hint 109-120:
LGTM!

The test function correctly verifies that an IncorrectRoleError is raised for the /start/ipa-query/{query_id} endpoint with a helper role.


133-136: LGTM!

The test function correctly verifies the /start/{query_id}/status endpoint when the query is not found.


139-145: LGTM!

The test function correctly verifies the /start/{running_query.query_id}/status endpoint when the query is running.


148-155: LGTM!

The test function correctly verifies the /start/{running_query.query_id}/status endpoint when the query is complete.


Line range hint 160-167:
LGTM!

The test function correctly verifies the /start/{query_id}/log-file endpoint.

server/app/query/page.tsx (3)

61-72: LGTM!

The useEffect hook correctly polls running queries every second.


74-94: LGTM!

The useEffect hook correctly updates the state with query data and status events based on query IDs.


95-190: LGTM!

The rendering logic correctly displays the query information based on the state.

server/app/header.tsx (1)

10-10: LGTM!

The navigation item change from "Dashboard" to "Queries" is correct and aligns with the new functionality.

server/app/query/servers.tsx (5)

38-42: LGTM!

The StatusEvent interface correctly defines the structure of a status event.


44-49: LGTM!

The buildStatusEventFromJSON function correctly builds a StatusEvent object from JSON data.


69-71: LGTM!

The StatusEventByRemoteServer type correctly defines the structure of status events by remote server.


83-86: LGTM!

The initialStatusEventByRemoteServer constant correctly initializes the status events by remote server.


126-130: LGTM!

The queryStatus method correctly fetches the query status.

server/app/query/view/[id]/page.tsx (6)

12-12: New imports look good!

The new imports StatusEvent and StatusEventByRemoteServer are necessary for the updated logic.

Also applies to: 22-27


54-55: New state variables look good!

The state variables statusEventByRemoteServer and initialStatusEventByRemoteServer are correctly initialized.


57-65: New function updateStatusEvent looks good!

The function correctly updates the statusEventByRemoteServer state.


123-123: Function call to updateStatusEvent looks good!

The function call is correctly implemented in openStatusSocket.


227-231: Updates to RunTimePill component look good!

The component is correctly updated to use statusEvent.

Also applies to: 242-242


276-280: Updates to StatusPill component look good!

The component is correctly updated to use statusEvent.

Also applies to: 291-291

sidecar/app/query/ipa.py (1)

254-254: URL path modification looks good!

The URL path construction is correctly modified from /start/ipa-helper/{self.query_id}/status to /start/{self.query_id}/status.

server/data/query.ts Outdated Show resolved Hide resolved
server/app/query/page.tsx Outdated Show resolved Hide resolved
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 801548f and 0c48568.

Files selected for processing (3)
  • server/app/query/page.tsx (1 hunks)
  • server/app/query/view/[id]/page.tsx (7 hunks)
  • server/data/query.ts (2 hunks)
Files skipped from review as they are similar to previous changes (3)
  • server/app/query/page.tsx
  • server/app/query/view/[id]/page.tsx
  • server/data/query.ts

if (data) {
return processQueryData(data);
} else {
notFound();
Copy link
Collaborator

Choose a reason for hiding this comment

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

that's a little weird but I guess the status of a sql query that returns no data does not have to be 404

Copy link
Member Author

Choose a reason for hiding this comment

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

Copy link
Collaborator

Choose a reason for hiding this comment

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

then it is probably better to check the status rather than request body before showing not found?

Copy link
Member Author

Choose a reason for hiding this comment

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

The query doesn't throw an error if nothing is found, so you check to see if it's empty. We could have it throw an error, by calling single() instead of maybeSingle(), but then we have to start parsing the error details to distinguish between not found and any other database error.

server/app/query/page.tsx Show resolved Hide resolved
server/app/query/page.tsx Outdated Show resolved Hide resolved
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Outside diff range, codebase verification and nitpick comments (2)
server/app/query/page.tsx (2)

29-61: Function logic looks good but consider adding comments for clarity.

The updateData function correctly updates the state with new status events. However, adding comments to explain the logic, especially the nested structure update, would improve readability.

+    // Update the state with new status events for the given query and remote server.
    setDataByQuery((prev) => {
      let _prev = prev;
      if (!Object.hasOwn(prev, query.uuid)) {
        // if queryID not in dataByQuery yet,
        // add initial status before updating value.
        // otherwise prev[query.uuid][statusEvent][remteServer.ServerName]
        // doesn't exist, and cannot be updated. we need to fill in the
        // nested structure, which `initialStatusEventByRemoteServer` does.
        _prev = {
          ..._prev,
          [query.uuid]: {
            statusEvent: initialStatusEventByRemoteServer,
            query: query,
          },
        };
      }

      return {
        ..._prev,
        [query.uuid]: {
          ..._prev[query.uuid],
          statusEvent: {
            ..._prev[query.uuid].statusEvent,
            [remoteServer.remoteServerName]: statusEvent,
          },
        },
      };
    });

110-114: Consider using a ternary operator for conditional rendering.

The conditional rendering for displaying messages when no queries are running can be simplified using a ternary operator.

-          {Object.keys(dataByQuery).length == 0 && (
-            <h3 className="text-lg font-bold leading-7 text-gray-900 sm:truncate sm:text-xl sm:tracking-tight">
-              None currently running.
-            </h3>
-          )}
+          {Object.keys(dataByQuery).length == 0 ? (
+            <h3 className="text-lg font-bold leading-7 text-gray-900 sm:truncate sm:text-xl sm:tracking-tight">
+              None currently running.
+            </h3>
+          ) : null}
Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 0c48568 and cfcb502.

Files selected for processing (4)
  • server/app/query/page.tsx (1 hunks)
  • server/app/query/view/[id]/components.tsx (3 hunks)
  • server/app/query/view/[id]/page.tsx (7 hunks)
  • sidecar/app/routes/websockets.py (1 hunks)
Files skipped from review due to trivial changes (1)
  • sidecar/app/routes/websockets.py
Files skipped from review as they are similar to previous changes (2)
  • server/app/query/view/[id]/components.tsx
  • server/app/query/view/[id]/page.tsx
Additional comments not posted (4)
server/app/query/page.tsx (4)

17-23: Type declarations look good.

The type declarations for QueryData and DataByQuery are correct and appropriately used in the code.


64-75: Polling mechanism looks good but consider adding a cleanup function.

The useEffect hook correctly polls running queries every second. Ensure the cleanup function is properly implemented to clear the interval.


116-196: Render logic for query details looks good.

The render logic correctly iterates over dataByQuery to display query details, including run times and statuses for each query.


1-14: Ensure all imports are necessary.

Review the imports to ensure they are all used in the file. Unused imports can be removed to keep the code clean.

Verification successful

All imports are necessary and used in the file.

The verification confirms that each import in server/app/query/page.tsx is utilized within the file.

  • useEffect and useState from "react"
  • Link from "next/link"
  • StatusPill and RunTimePill from "@/app/query/view/[id]/components"
  • StatusEvent, RemoteServer, RemoteServerNames, IPARemoteServers, StatusEventByRemoteServer, and initialStatusEventByRemoteServer from "@/app/query/servers"
  • getQueryByUUID and Query from "@/data/query"
Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify all imports are used in the file.

# Test: Search for the usage of each import. Expect: Each import should be used at least once.
rg --type js --type ts --type tsx 'useEffect|useState|Link|StatusPill|RunTimePill|StatusEvent|RemoteServer|RemoteServerNames|IPARemoteServers|StatusEventByRemoteServer|initialStatusEventByRemoteServer|getQueryByUUID|Query' server/app/query/page.tsx

Length of output: 278


Script:

#!/bin/bash
# Description: Verify all imports are used in the file.

# Test: Search for the usage of each import. Expect: Each import should be used at least once.
rg 'useEffect|useState|Link|StatusPill|RunTimePill|StatusEvent|RemoteServer|RemoteServerNames|IPARemoteServers|StatusEventByRemoteServer|initialStatusEventByRemoteServer|getQueryByUUID|Query' server/app/query/page.tsx

Length of output: 2487

Comment on lines +77 to +100
useEffect(() => {
(async () => {
setDataByQuery((prev) => {
return Object.fromEntries(
Object.keys(prev)
.filter((queryID) => queryIDs.includes(queryID))
.map((queryID) => [queryID, prev[queryID]]),
);
});

const promises = queryIDs.map(async (queryID) => {
const query: Query = await getQueryByUUID(queryID);
const remoteServerPromises = Object.values(IPARemoteServers).map(
async (remoteServer) => {
const statusEvent: StatusEvent =
await remoteServer.queryStatus(queryID);
updateData(query, remoteServer, statusEvent);
},
);
await Promise.all(remoteServerPromises);
});
await Promise.all(promises);
})();
}, [queryIDs]);
Copy link
Contributor

Choose a reason for hiding this comment

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

Consider using Promise.all for concurrent requests.

The useEffect hook correctly updates the state based on the current query IDs. However, using Promise.all for concurrent requests to remote servers can improve efficiency.

    const promises = queryIDs.map(async (queryID) => {
      const query: Query = await getQueryByUUID(queryID);
      const remoteServerPromises = Object.values(IPARemoteServers).map(
        async (remoteServer) => {
          const statusEvent: StatusEvent =
            await remoteServer.queryStatus(queryID);
          updateData(query, remoteServer, statusEvent);
        },
      );
-      await Promise.all(remoteServerPromises);
+      return Promise.all(remoteServerPromises);
    });
    await Promise.all(promises);
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
useEffect(() => {
(async () => {
setDataByQuery((prev) => {
return Object.fromEntries(
Object.keys(prev)
.filter((queryID) => queryIDs.includes(queryID))
.map((queryID) => [queryID, prev[queryID]]),
);
});
const promises = queryIDs.map(async (queryID) => {
const query: Query = await getQueryByUUID(queryID);
const remoteServerPromises = Object.values(IPARemoteServers).map(
async (remoteServer) => {
const statusEvent: StatusEvent =
await remoteServer.queryStatus(queryID);
updateData(query, remoteServer, statusEvent);
},
);
await Promise.all(remoteServerPromises);
});
await Promise.all(promises);
})();
}, [queryIDs]);
useEffect(() => {
(async () => {
setDataByQuery((prev) => {
return Object.fromEntries(
Object.keys(prev)
.filter((queryID) => queryIDs.includes(queryID))
.map((queryID) => [queryID, prev[queryID]]),
);
});
const promises = queryIDs.map(async (queryID) => {
const query: Query = await getQueryByUUID(queryID);
const remoteServerPromises = Object.values(IPARemoteServers).map(
async (remoteServer) => {
const statusEvent: StatusEvent =
await remoteServer.queryStatus(queryID);
updateData(query, remoteServer, statusEvent);
},
);
return Promise.all(remoteServerPromises);
});
await Promise.all(promises);
})();
}, [queryIDs]);

@eriktaubeneck eriktaubeneck merged commit 0bb24ad into main Jul 19, 2024
3 checks passed
@eriktaubeneck eriktaubeneck deleted the running-queries branch July 19, 2024 06:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants