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

fix(indexer): new graphql url config option #1303

Merged
merged 4 commits into from
Feb 25, 2025

Conversation

mrnaveira
Copy link
Collaborator

@mrnaveira mrnaveira commented Feb 21, 2025

Description

  • New config option in the indexer and tari_swarm to specify the public address of the GraphQL API
  • The indexer web ui now calls a new /graphql_address endpoint to get the actual GraphQL URL, in similar fashion as the JSON RPC URL.

Motivation and Context

When deploying on ContractNet, the events page is empty. This is due to the GraphQL URL being hardcoded to localhost.

This PR fixes it by parameterizing the public address in a similar way to what we already do for the JSON RPC public address

How Has This Been Tested?

Locally spawning tari_swarm and using the indexer web ui

What process can a PR reviewer use to test or verify this change?

See previous section

Breaking Changes

  • None
  • Requires data directory to be deleted
  • Other - Please specify

Summary by CodeRabbit

  • New Features

    • Introduced a new optional field for the public GraphQL API endpoint alongside the existing JSON RPC.
    • Enhanced the HTTP interface to dynamically provide the GraphQL API address for improved connectivity.
    • Expanded functionality to retrieve and return GraphQL URLs in various components.
  • Documentation

    • Updated documentation to clarify the usage of JSON RPC and GraphQL endpoints.

stringhandler
stringhandler previously approved these changes Feb 21, 2025
Copy link

coderabbitai bot commented Feb 21, 2025

Walkthrough

The changes introduce support for a GraphQL API endpoint by adding new configuration fields and updating existing documentation. The HTTP UI server now accepts a GraphQL address and returns it via a dedicated endpoint. Additionally, the indexer startup flow and swarm daemon components have been updated to allocate ports, include command parameters, and generate public URLs for GraphQL. The web UI now dynamically retrieves the GraphQL address, replacing a hardcoded value.

Changes

File(s) Change Summary
applications/tari_indexer/src/cli.rs
applications/tari_indexer/src/config.rs
Added new optional field web_ui_public_graphql_url with documentation updates. The config now initializes this field to None and clarifies the JSON RPC address documentation.
applications/tari_indexer/src/http_ui/server.rs
applications/tari_indexer_web_ui/src/routes/Events/Events.tsx
applications/tari_indexer_web_ui/src/utils/graphql.tsx
Updated run_http_ui_server to accept an extra graphql_address parameter and added a new route (/graphql_address). The web UI replaces a hardcoded indexer address with a dynamically fetched GraphQL address through a new utility function.
applications/tari_indexer/src/lib.rs
applications/tari_swarm_daemon/src/process_definitions/context.rs
applications/tari_swarm_daemon/src/process_definitions/indexer.rs
applications/tari_swarm_daemon/src/process_manager/handle.rs
applications/tari_swarm_daemon/src/webserver/rpc/indexers.rs
Modified indexer startup logic to integrate an EventManager and conditionally launch the GraphQL API. New methods generate public GraphQL URLs and update the command configuration with GraphQL ports and listener addresses. The swarm daemon now supports returning GraphQL endpoints alongside JSON RPC.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant HTTP_Server
    Client->>HTTP_Server: GET /graphql_address
    HTTP_Server-->>Client: Returns graphql_address string
Loading
sequenceDiagram
    participant Indexer
    participant EventManager
    participant Config
    Indexer->>Config: Read public JSON RPC & GraphQL addresses
    Config-->>Indexer: Return addresses
    Indexer->>EventManager: Instantiate with dependency components
    alt Both addresses available
        Indexer->>Indexer: Start GraphQL API and JSON-RPC API
    else Address missing
        Indexer->>Indexer: Skip API startup
    end
Loading

Poem

I hop through fields of code with glee,
Discovering GraphQL in each new key.
Routes and servers now sing a tune,
As command flows dance beneath the moon.
With joyful leaps, my code’s set free—
A rabbit's dream in tech harmony! 🐇✨


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9d4730d and 664047d.

📒 Files selected for processing (5)
  • applications/tari_indexer/src/cli.rs (2 hunks)
  • applications/tari_indexer/src/config.rs (2 hunks)
  • applications/tari_indexer/src/http_ui/server.rs (1 hunks)
  • applications/tari_indexer/src/lib.rs (2 hunks)
  • applications/tari_swarm_daemon/src/process_definitions/context.rs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • applications/tari_indexer/src/config.rs
  • applications/tari_swarm_daemon/src/process_definitions/context.rs
  • applications/tari_indexer/src/http_ui/server.rs
⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: test
  • GitHub Check: machete
  • GitHub Check: check nightly
  • GitHub Check: check stable
  • GitHub Check: clippy
🔇 Additional comments (5)
applications/tari_indexer/src/cli.rs (2)

59-64: Documentation updated and new parameter added for GraphQL URL.

The changes correctly:

  1. Update the documentation for web_ui_public_json_rpc_url to clarify it's for JSON RPC (not Web UI)
  2. Add a new parameter web_ui_public_graphql_url for specifying the GraphQL API address

These changes properly support the PR objective of allowing users to specify the public address of the GraphQL API.


102-104: Configuration override for GraphQL URL correctly implemented.

The implementation follows the same pattern as other configuration overrides in this file, maintaining consistency with the existing codebase.

applications/tari_indexer/src/lib.rs (3)

140-151: Event manager and GraphQL server initialization implemented properly.

The code correctly:

  1. Initializes the EventManager with appropriate dependencies
  2. Conditionally starts the GraphQL server when an address is configured
  3. Logs the server startup with consistent formatting

This implementation aligns with the PR objective of supporting the GraphQL API endpoint.


179-189: GraphQL address handling implemented properly.

The code follows the same pattern as the JSON-RPC address handling with proper validation and error handling:

  1. Uses the configured public address or falls back to the local address
  2. Ensures the URL has the correct protocol
  3. Validates the URL format with appropriate error messaging

This implementation is well-structured and consistent with the existing codebase.


190-190: HTTP UI server updated to support GraphQL.

The function call to run_http_ui_server is correctly updated to include the GraphQL address, which matches the PR objective of allowing the indexer web UI to retrieve the actual GraphQL URL.

✨ Finishing Touches
  • 📝 Generate Docstrings (Beta)

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>, please review it.
    • 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 gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @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 using 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 generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

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.

Copy link

@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: 3

🧹 Nitpick comments (4)
applications/tari_indexer_web_ui/src/utils/graphql.tsx (1)

1-1: Fix the copyright year.

The copyright year is set to 2025, which is incorrect as it's beyond the current year.

-//  Copyright 2025. The Tari Project
+//  Copyright 2024. The Tari Project
applications/tari_indexer/src/config.rs (1)

89-91: Fix typo in GraphQL URL documentation.

The documentation contains a typo: "jrpc" should be "GraphQL" since this is referring to the GraphQL API.

-    /// The jrpc address where the UI should connect to the GraphQL API(it can be the same as the json_rpc_address, but doesn't have to
+    /// The GraphQL address where the UI should connect to the GraphQL API (it can be the same as the graphql_address, but doesn't have to
applications/tari_indexer_web_ui/src/routes/Events/Events.tsx (1)

62-64: Consider removing debug console.log.

The console.log statement might be useful during development but should be removed or wrapped in a debug flag for production.

    let indexer_address = (await getGraphQLAddress()).toString();
-    console.log({indexer_address});
applications/tari_indexer/src/lib.rs (1)

190-191: Consider adding error handling for the HTTP UI server.

The HTTP UI server is spawned without any error handling. Consider adding error handling to log any startup issues.

Apply this diff to add error handling:

-            task::spawn(run_http_ui_server(address, public_jrpc_address, public_graphql_address));
+            task::spawn({
+                let address = address.clone();
+                async move {
+                    if let Err(e) = run_http_ui_server(address, public_jrpc_address, public_graphql_address).await {
+                        error!(target: LOG_TARGET, "Failed to start HTTP UI server: {}", e);
+                    }
+                }
+            });
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 249a0f3 and 9d4730d.

📒 Files selected for processing (10)
  • applications/tari_indexer/src/cli.rs (2 hunks)
  • applications/tari_indexer/src/config.rs (2 hunks)
  • applications/tari_indexer/src/http_ui/server.rs (1 hunks)
  • applications/tari_indexer/src/lib.rs (3 hunks)
  • applications/tari_indexer_web_ui/src/routes/Events/Events.tsx (2 hunks)
  • applications/tari_indexer_web_ui/src/utils/graphql.tsx (1 hunks)
  • applications/tari_swarm_daemon/src/process_definitions/context.rs (1 hunks)
  • applications/tari_swarm_daemon/src/process_definitions/indexer.rs (2 hunks)
  • applications/tari_swarm_daemon/src/process_manager/handle.rs (1 hunks)
  • applications/tari_swarm_daemon/src/webserver/rpc/indexers.rs (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: test
  • GitHub Check: check stable
  • GitHub Check: check nightly
  • GitHub Check: clippy
🔇 Additional comments (18)
applications/tari_swarm_daemon/src/webserver/rpc/indexers.rs (2)

25-25: LGTM! The graphql field is correctly added to the IndexerInfo struct.

The field follows the same pattern as the existing jrpc field, maintaining consistency in the data structure.


36-36: LGTM! The GraphQL URL is correctly retrieved and included in the response.

The implementation follows the same pattern as the existing JSON-RPC URL handling.

Also applies to: 44-44

applications/tari_indexer_web_ui/src/utils/graphql.tsx (1)

23-27: LGTM! The GraphQL URL handling is well-implemented.

The implementation includes:

  • Environment variable configuration with fallback
  • Comprehensive error handling
  • Default URL fallback

Also applies to: 29-45

applications/tari_swarm_daemon/src/process_definitions/indexer.rs (2)

26-26: LGTM! The GraphQL port allocation is correctly implemented.

The implementation follows the same pattern as the existing JSON-RPC and web UI ports.

Also applies to: 31-31, 33-33


58-58: LGTM! The GraphQL command arguments are correctly added.

The implementation follows the same pattern as the existing JSON-RPC arguments.

Also applies to: 61-61

applications/tari_indexer/src/http_ui/server.rs (1)

38-38: LGTM! The GraphQL address endpoint is correctly implemented.

The implementation:

  • Correctly updates the function signature
  • Follows the same pattern as the existing JSON-RPC endpoint

Also applies to: 43-43

applications/tari_swarm_daemon/src/process_definitions/context.rs (2)

96-99: LGTM: Error message clarification in JSON RPC URL method.

The error message has been updated to be more specific about the URL type.


101-117: LGTM: Well-structured GraphQL URL implementation.

The new get_public_graphql_url method follows the established pattern, with proper error handling and fallback to default IP.

applications/tari_indexer/src/cli.rs (3)

59-61: LGTM: Improved documentation clarity for JSON RPC URL.

The documentation now correctly specifies this is for the JSON RPC address.


62-64: LGTM: Well-documented GraphQL URL configuration.

The new option is properly documented and includes environment variable support.


102-107: LGTM: Consistent configuration override handling.

The GraphQL URL override follows the same pattern as other configuration options.

applications/tari_indexer/src/config.rs (2)

86-88: LGTM: Improved documentation for JSON RPC URL configuration.

The documentation clearly explains the fallback behavior.


137-137: LGTM: Proper default initialization.

The new field is correctly initialized to None in the default implementation.

applications/tari_indexer_web_ui/src/routes/Events/Events.tsx (2)

35-35: LGTM: Clean utility function import.

The GraphQL utility function is properly imported.


65-65: LGTM: Dynamic GraphQL address integration.

The fetch call now correctly uses the dynamically retrieved GraphQL address.

applications/tari_indexer/src/lib.rs (3)

140-144: LGTM!

The event manager initialization is clean and follows good practices by using Arc for shared ownership.


146-151: LGTM!

The GraphQL server startup is well-implemented with proper logging and error handling.


179-189: LGTM!

The public GraphQL URL handling follows the same pattern as the JSON-RPC URL handling, ensuring consistency in the codebase.

try {
return new URL(url);
} catch (e) {
throw new Error(`Invalid URL: ${url} : {e}`);
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix the template literal syntax in error message.

The error message has incorrect template literal syntax for the error object.

-        throw new Error(`Invalid URL: ${url} : {e}`);
+        throw new Error(`Invalid URL: ${url} : ${e}`);
📝 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
throw new Error(`Invalid URL: ${url} : {e}`);
throw new Error(`Invalid URL: ${url} : ${e}`);

Comment on lines +118 to +133
pub fn get_public_graphql_url(&self) -> Url {
match self.settings.get("public_graphql_url") {
Some(url) => url.parse().expect("Invalid JSON RPC URL"),
None => {
let public_ip = self
.settings
.get("public_ip")
.map(|s| s.as_str())
.unwrap_or("127.0.0.1");
let web_port = self.ports.get("jrpc").expect("jrpc port not found");
format!("http://{public_ip}:{web_port}/json_rpc")
.parse()
.expect("Invalid web URL")
},
}
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix incorrect URL construction in get_public_graphql_url.

The method has two issues:

  1. It's incorrectly using the JSON-RPC port and path for the GraphQL URL.
  2. The error messages mention "JSON RPC URL" instead of "GraphQL URL".

Apply this diff to fix the issues:

    pub fn get_public_graphql_url(&self) -> Url {
        match self.settings.get("public_graphql_url") {
-            Some(url) => url.parse().expect("Invalid JSON RPC URL"),
+            Some(url) => url.parse().expect("Invalid GraphQL URL"),
            None => {
                let public_ip = self
                    .settings
                    .get("public_ip")
                    .map(|s| s.as_str())
                    .unwrap_or("127.0.0.1");
-                let web_port = self.ports.get("jrpc").expect("jrpc port not found");
-                format!("http://{public_ip}:{web_port}/json_rpc")
+                let web_port = self.ports.get("web").expect("web port not found");
+                format!("http://{public_ip}:{web_port}/graphql")
                    .parse()
-                    .expect("Invalid web URL")
+                    .expect("Invalid GraphQL URL")
            },
        }
    }
📝 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
pub fn get_public_graphql_url(&self) -> Url {
match self.settings.get("public_graphql_url") {
Some(url) => url.parse().expect("Invalid JSON RPC URL"),
None => {
let public_ip = self
.settings
.get("public_ip")
.map(|s| s.as_str())
.unwrap_or("127.0.0.1");
let web_port = self.ports.get("jrpc").expect("jrpc port not found");
format!("http://{public_ip}:{web_port}/json_rpc")
.parse()
.expect("Invalid web URL")
},
}
}
pub fn get_public_graphql_url(&self) -> Url {
match self.settings.get("public_graphql_url") {
Some(url) => url.parse().expect("Invalid GraphQL URL"),
None => {
let public_ip = self
.settings
.get("public_ip")
.map(|s| s.as_str())
.unwrap_or("127.0.0.1");
let web_port = self.ports.get("web").expect("web port not found");
format!("http://{public_ip}:{web_port}/graphql")
.parse()
.expect("Invalid GraphQL URL")
},
}
}

Comment on lines +155 to 156
if let (Some(jrpc_address), Some(graphql_address)) = (jrpc_address, graphql_address) {
info!(target: LOG_TARGET, "🌐 Started JSON-RPC server on {}", jrpc_address);
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Reconsider the dependency between JSON-RPC and GraphQL servers.

The JSON-RPC server startup now requires the GraphQL address to be configured, which creates an unnecessary dependency between these services. They should be able to operate independently.

Apply this diff to decouple the services:

-    if let (Some(jrpc_address), Some(graphql_address)) = (jrpc_address, graphql_address) {
+    if let Some(jrpc_address) = jrpc_address {
📝 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
if let (Some(jrpc_address), Some(graphql_address)) = (jrpc_address, graphql_address) {
info!(target: LOG_TARGET, "🌐 Started JSON-RPC server on {}", jrpc_address);
if let Some(jrpc_address) = jrpc_address {
info!(target: LOG_TARGET, "🌐 Started JSON-RPC server on {}", jrpc_address);

Copy link

github-actions bot commented Feb 21, 2025

Test Results (CI)

617 tests  ±0   616 ✅ ±0   3h 28m 1s ⏱️ - 13m 28s
 67 suites ±0     0 💤 ±0 
  2 files   ±0     1 ❌ ±0 

For more details on these failures, see this check.

Results for commit dabc8cf. ± Comparison against base commit 737599c.

♻️ This comment has been updated with latest results.

@sdbondi sdbondi enabled auto-merge February 25, 2025 15:44
@sdbondi sdbondi added this pull request to the merge queue Feb 25, 2025
Merged via the queue into tari-project:development with commit 86f378e Feb 25, 2025
12 of 13 checks passed
sdbondi added a commit to sdbondi/tari-dan that referenced this pull request Feb 26, 2025
sdbondi added a commit that referenced this pull request Feb 26, 2025
Description
---
Fix indexer config that requires JSONRPC and GraphQL to both be
configured for web to work.
Correct GraphQL url
Clear terminated instances from list
Display settings in swarm UI

Motivation and Context
---

#1303 (review)

How Has This Been Tested?
---
Manually

What process can a PR reviewer use to test or verify this change?
---
Run swarm

Breaking Changes
---

- [x] None
- [ ] Requires data directory to be deleted
- [ ] Other - Please specify

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- The node details view now includes a clickable GraphQL endpoint link,
enhancing accessibility.
- Instance management has been improved with capabilities for 
removal and automatic cleanup of terminated instances.
  
- **Bug Fixes**
- Error messages have been refined to provide clearer guidance for
configuration issues, reducing unexpected runtime interruptions.
- Enhanced error handling for invalid URL formats in GraphQL address
retrieval.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants