Skip to content

Local and Remote execution defect fix#4344

Merged
Maheshkale447 merged 2 commits into
Releases/Official-Releasefrom
BugFix/RemoteExecutionRefresh
Oct 17, 2025
Merged

Local and Remote execution defect fix#4344
Maheshkale447 merged 2 commits into
Releases/Official-Releasefrom
BugFix/RemoteExecutionRefresh

Conversation

@AmanPrasad43

@AmanPrasad43 AmanPrasad43 commented Oct 17, 2025

Copy link
Copy Markdown
Contributor

Thank you for your contribution.
Before submitting this PR, please make sure:

  • PR description and commit message should describe the changes done in this PR
  • Verify the PR is pointing to correct branch i.e. Release or Beta branch if the code fix is for specific release , else point it to master
  • Latest Code from master or specific release branch is merged to your branch
  • No unwanted\commented\junk code is included
  • No new warning upon build solution
  • Code Summary\Comments are added to my code which explains what my code is doing
  • Existing unit test cases are passed
  • New Unit tests are added for your development
  • Sanity Tests are successfully executed for New and Existing Functionality
  • Verify that changes are compatible with all relevant browsers and platforms.
  • After creating pull request there should not be any conflicts
  • Resolve all Codacy comments
  • Builds and checks are passed before PR is sent for review
  • Resolve code review comments
  • Update the Help Library document to match any feature changes

Summary by CodeRabbit

  • New Features
    • Added remote endpoint health checks before enabling remote data loading so the app only attempts GraphQL communication when the endpoint is responsive.
  • Bug Fixes
    • Improved error handling and fail-safe behavior when remote logging or endpoint checks fail, preventing partial or unreliable remote data attempts and updating related UI states.

@coderabbitai

coderabbitai Bot commented Oct 17, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

AssignGraphQLObjectEndPoint() in RunSetsExecutionsHistoryPage.xaml.cs now validates GraphQL availability before initializing clients: it checks PublishLogToCentralDB, retrieves the endpoint, performs a 3-second HTTP POST introspection health check (using System.Text.Json/System.Text.Encoding), logs and disables GraphQL on failures, and only initializes clients on success.

Changes

Cohort / File(s) Change Summary
GraphQL Endpoint Health-Check Validation
Ginger/Ginger/Run/RunSetsExecutionsHistoryPage.xaml.cs
Added pre-initialization flow that: checks PublishLogToCentralDB, retrieves endpoint, performs a 3s HTTP POST health check with a GraphQL introspection query using System.Text.Json/System.Text.Encoding, logs warnings and disables GraphQL on failure, ensures isGraphQlClinetConfigure is false on exceptions, and initializes GraphQlClient/ExecutionReportGraphQLClient only on successful health check.

Sequence Diagram

sequenceDiagram
    participant Caller
    participant Assign as AssignGraphQLObjectEndPoint()
    participant Config
    participant HTTP as HTTP Client
    participant GraphQL as GraphQL Client

    Caller->>Assign: invoke
    Assign->>Config: read PublishLogToCentralDB
    alt Publish disabled or config null
        Assign->>Config: set GraphQL disabled
        Assign-->>Caller: return false
    else Publish enabled
        Assign->>Config: get endpoint URL
        alt endpoint empty
            Assign->>Config: set GraphQL disabled
            Assign-->>Caller: return false
        else endpoint exists
            rect rgb(230,245,255)
                note over Assign,HTTP: Health-check phase (POST introspection, 3s timeout)
                Assign->>HTTP: POST introspection query
                HTTP-->>Assign: response / timeout / error
            end
            alt health check fails
                Assign->>Config: log warning, disable GraphQL
                Assign-->>Caller: return false
            else health check succeeds
                Assign->>GraphQL: initialize GraphQlClient & ExecutionReportGraphQLClient
                Assign->>Config: set GraphQL enabled
                Assign-->>Caller: return true
            end
        end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • Maheshkale447

Poem

🐰 A three-second hop to the GraphQL tree,

I poke the endpoint to see if it's free,
If it answers true, clients spring to life,
If not, I log warnings and avoid the strife —
🥕 small checks, big peace, from this rabbit to thee.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Description Check ⚠️ Warning The PR description fails to meet the template requirements as it contains only the unchecked template checklist items with no actual description of the changes. The first and most critical item in the template—"PR description and commit message should describe the changes done in this PR"—is not satisfied, as no meaningful description of the modifications to RunSetsExecutionsHistoryPage is provided. The author appears to have copied the template without filling it out or addressing any of the checklist items, leaving reviewers without essential context about the purpose and impact of the changes. The PR description should include a summary of what was changed, why it was changed, and how it addresses the "Local and Remote execution defect." The author should fill out the PR description with an actual summary of the changes before the PR can be merged. This should include a clear explanation of the GraphQL endpoint validation logic added, the health check mechanism implemented, why these changes fix the local and remote execution defect, and verification that the applicable checklist items have been addressed (such as confirming unit tests were added, sanity testing was performed, and the PR targets the correct branch).
Title Check ❓ Inconclusive The title "Local and Remote execution defect fix" is related to the changeset, as the modifications do involve GraphQL endpoint configuration for remote execution. However, the title is vague and lacks specificity about what the actual fix entails. The term "defect fix" is generic and doesn't convey meaningful technical information about the core changes, which involve GraphQL health checking, endpoint validation, and client initialization logic. While the title references real aspects of the change, a developer scanning history would not understand the specific nature of the improvements without examining the detailed code changes. Consider revising the title to be more specific about the actual technical change, such as "Add GraphQL endpoint health validation and configuration logic" or "Implement GraphQL endpoint validation before client initialization." This would give reviewers and future readers a clearer understanding of the core improvements without requiring them to examine the full changeset.
✅ Passed checks (1 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch BugFix/RemoteExecutionRefresh

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
Ginger/Ginger/Run/RunSetsExecutionsHistoryPage.xaml.cs (2)

303-311: Resource leak: _runsetFromReportLoader.Dispose() gated by _httpClient != null

The _runsetFromReportLoader implements IDisposable and must be disposed unconditionally. Currently, if _httpClient is null, the loader is never disposed. Apply this diff:

         private void OnUnloaded(object sender, RoutedEventArgs e)
         {
+            _runsetFromReportLoader?.Dispose();
             if (_httpClient != null)
             {
                 _httpClient.Dispose();
                 _httpClient = null;
-                _runsetFromReportLoader.Dispose();
             }
         }

Optionally remove the unused _httpClient field. GraphQlClient and ExecutionReportGraphQLClient do not implement IDisposable, so no additional disposals are needed.


167-217: Verification complete. All core concerns confirmed; fix addresses critical UI-blocking bug and auth gap.

Verification findings:

  • UI-blocking bug (CRITICAL): Confirmed. HttpClient.PostAsync(...).Result at line 201 blocks synchronously on UI thread when called from RemoteRadioButton_Selected (line 261, async void event) and ReloadExecutionHistoryData (line 325, public void). This freezes the WPF UI during the 3-second health check.
  • Missing auth headers (VALID GAP): Confirmed. GraphQLHttpClient v6.1.0 constructor accepts only (endpoint, serializer) with no auth parameter. GraphQL queries use no Bearer tokens or auth headers. Health check currently blind to authentication that real queries require. Codebase patterns for Bearer tokens exist (e.g., General.cs line 1352, SealightsReportApiHandler.cs line 164).
  • Variable shadowing (CONFIRMED): Local response variable shadows field at line 201.
  • Proposed diff is appropriate: Async conversion with CancellationToken, renamed variable, TODO for auth wiring.

Convert to async and wire auth headers into health-check request

Synchronous .Result on HttpClient.PostAsync at line 201 blocks the WPF UI thread during 3-second health checks. Called from UI event handlers (RemoteRadioButton_Selected, line 261; ReloadExecutionHistoryData, line 325), causing UI freeze.

Also: health-check omits auth headers the GraphQL client uses → false negatives on secured endpoints. Local variable response shadows a field (readability).

Apply the provided diff to:

  • Convert AssignGraphQLObjectEndPoint() to AssignGraphQLObjectEndPointAsync()
  • Use await with CancellationTokenSource instead of .Result
  • Rename response to httpResponse
  • Update call sites at lines 261 and 325 to await
  • Add TODO to propagate auth headers (Bearer token, etc.) to match real GraphQL client auth

For the auth implementation: confirm with the server provider whether GraphQL endpoints require Bearer tokens or other auth schemes, then retrieve and attach those headers in the health-check request via request.Headers.Authorization or similar.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f64d8bd and f665721.

📒 Files selected for processing (1)
  • Ginger/Ginger/Run/RunSetsExecutionsHistoryPage.xaml.cs (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
Ginger/Ginger/Run/RunSetsExecutionsHistoryPage.xaml.cs (3)
Ginger/GingerCoreCommon/ReportsLib/ExecutionLoggerConfiguration.cs (1)
  • ExecutionLoggerConfiguration (26-412)
Ginger/GingerCoreNET/Run/GingerRemoteExecutionUtils.cs (2)
  • GingerRemoteExecutionUtils (35-178)
  • GetReportDataServiceUrl (74-83)
Ginger/GingerCoreCommon/ReporterLib/Reporter.cs (1)
  • Reporter (28-357)
🔇 Additional comments (1)
Ginger/Ginger/Run/RunSetsExecutionsHistoryPage.xaml.cs (1)

49-49: Import OK

System.Text is required for Encoding.UTF8 usage in the health‑check payload.

Comment thread Ginger/Ginger/Run/RunSetsExecutionsHistoryPage.xaml.cs Outdated
Comment thread Ginger/Ginger/Run/RunSetsExecutionsHistoryPage.xaml.cs
Comment thread Ginger/Ginger/Run/RunSetsExecutionsHistoryPage.xaml.cs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f665721 and d1ece52.

📒 Files selected for processing (1)
  • Ginger/Ginger/Run/RunSetsExecutionsHistoryPage.xaml.cs (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
Ginger/Ginger/Run/RunSetsExecutionsHistoryPage.xaml.cs (3)
Ginger/GingerCoreCommon/ReportsLib/ExecutionLoggerConfiguration.cs (1)
  • ExecutionLoggerConfiguration (26-412)
Ginger/GingerCoreNET/Run/GingerRemoteExecutionUtils.cs (2)
  • GingerRemoteExecutionUtils (35-178)
  • GetReportDataServiceUrl (74-83)
Ginger/GingerCoreCommon/ReporterLib/Reporter.cs (1)
  • Reporter (28-357)
🔇 Additional comments (6)
Ginger/Ginger/Run/RunSetsExecutionsHistoryPage.xaml.cs (6)

49-49: LGTM! Import added for health check encoding.

The System.Text import is necessary to support Encoding.UTF8 used in the GraphQL health check content serialization.


171-175: LGTM! Null safety properly implemented.

The null check for execLoggerConfig and the check for PublishLogToCentralDB.No correctly prevent initialization when remote execution logging is disabled or configuration is unavailable.


176-181: LGTM! Endpoint retrieval with proper validation.

The endpoint retrieval and empty check correctly handle the case where the report service URL is not configured.


183-184: LGTM! Defensive URL composition implemented.

The use of TrimEnd('/') before appending /api/graphql prevents double-slash issues and is consistent with defensive coding practices.


212-216: LGTM! Client initialization after successful health check.

The GraphQL clients are properly initialized only after the health check confirms the endpoint is available, preventing failed operations downstream.


218-223: LGTM! Improved error handling with descriptive message.

The error message clearly indicates the health check or connection failure, and the flag is properly reset to prevent use of an unconfigured client.

Comment on lines +185 to +210
// GraphQL POST health check
using (var httpClient = new HttpClient())
{
httpClient.Timeout = TimeSpan.FromSeconds(3);

var healthCheckQuery = new
{
query = "{ __typename }"
};

var content = new StringContent(
System.Text.Json.JsonSerializer.Serialize(healthCheckQuery),
Encoding.UTF8,
"application/json"
);

HttpResponseMessage graphQLresponse = httpClient.PostAsync(graphQlUrl, content).Result;

if (!graphQLresponse.IsSuccessStatusCode)
{
Reporter.ToLog(eLogLevel.WARN,
$"GraphQL endpoint responded with {graphQLresponse.StatusCode}. Marking as unavailable.");
isGraphQlClinetConfigure = false;
return false;
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Risk of deadlock: avoid blocking async with .Result in UI contexts.

Line 201 uses .Result to block synchronously on PostAsync() in a WPF Page context. This pattern can cause deadlocks when the continuation tries to marshal back to the UI thread.

Refactor AssignGraphQLObjectEndPoint() to be async:

-        private bool AssignGraphQLObjectEndPoint()
+        private async Task<bool> AssignGraphQLObjectEndPoint()
         {
             try
             {
                 if (execLoggerConfig == null || execLoggerConfig.PublishLogToCentralDB == ExecutionLoggerConfiguration.ePublishToCentralDB.No)
                 {
                     isGraphQlClinetConfigure = false;
                     return false;
                 }
                 string endPoint = GingerRemoteExecutionUtils.GetReportDataServiceUrl();
                 if (string.IsNullOrEmpty(endPoint))
                 {
                     isGraphQlClinetConfigure = false;
                     return false;
                 }
 
                 string graphQlUrl = $"{endPoint.TrimEnd('/')}/api/graphql";
 
                 // GraphQL POST health check
                 using (var httpClient = new HttpClient())
                 {
                     httpClient.Timeout = TimeSpan.FromSeconds(3);
 
                     var healthCheckQuery = new
                     {
                         query = "{ __typename }"
                     };
 
                     var content = new StringContent(
                         System.Text.Json.JsonSerializer.Serialize(healthCheckQuery),
                         Encoding.UTF8,
                         "application/json"
                     );
 
-                    HttpResponseMessage graphQLresponse = httpClient.PostAsync(graphQlUrl, content).Result;
+                    HttpResponseMessage graphQLresponse = await httpClient.PostAsync(graphQlUrl, content);
 
                     if (!graphQLresponse.IsSuccessStatusCode)
                     {
                         Reporter.ToLog(eLogLevel.WARN,
                             $"GraphQL endpoint responded with {graphQLresponse.StatusCode}. Marking as unavailable.");
                         isGraphQlClinetConfigure = false;
                         return false;
                     }
                 }
 
                 // healthy, initialize the client
                 graphQlClient = new GraphQlClient(graphQlUrl);
                 executionReportGraphQLClient = new ExecutionReportGraphQLClient(graphQlClient);
                 isGraphQlClinetConfigure = true;
                 return true;
             }
             catch (Exception ex)
             {
                 Reporter.ToLog(eLogLevel.ERROR, "Error while verifying or connecting GraphQL endpoint.", ex);
                 isGraphQlClinetConfigure = false;
                 return false;
             }
         }

Then update all call sites (lines 261, 325) to await the method:

-            if (SetExectionHistoryVisibility(execLoggerConfig) && AssignGraphQLObjectEndPoint())
+            if (SetExectionHistoryVisibility(execLoggerConfig) && await AssignGraphQLObjectEndPoint())
-            if (AssignGraphQLObjectEndPoint() && SetExectionHistoryVisibility(execLoggerConfig))
+            if (await AssignGraphQLObjectEndPoint() && SetExectionHistoryVisibility(execLoggerConfig))

Committable suggestion skipped: line range outside the PR's diff.

@Maheshkale447
Maheshkale447 merged commit 0fbbc6d into Releases/Official-Release Oct 17, 2025
5 of 9 checks passed
@Maheshkale447
Maheshkale447 deleted the BugFix/RemoteExecutionRefresh branch October 17, 2025 18:58
@coderabbitai coderabbitai Bot mentioned this pull request Oct 17, 2025
15 tasks
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