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

[dotnet] Avoid performing JSON serialization in debugger display #14734

Closed
wants to merge 0 commits into from

Conversation

RenderMichael
Copy link
Contributor

@RenderMichael RenderMichael commented Nov 9, 2024

User description

Thanks for contributing to Selenium!
A PR well described will help maintainers to quickly review and merge it

Before submitting your PR, please check our contributing guidelines.
Avoid large PRs, help reviewers by making them as simple and short as possible.

Description

Inspired by conversion in #14726

Motivation and Context

The debugger display should provide a very brief snapshot of the object's values (the user can expand the object if they want to see everything). Performing JSON serialization is antithetical to that, and can result in performance issues.

image

image

image

image

image

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist

  • I have read the contributing document.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

PR Type

enhancement


Description

  • Added DebuggerDisplay attributes to DriverOptions, ReturnedCapabilities, and RemoteSessionSettings classes to improve debugging experience.
  • Implemented GetDebuggerDisplay methods to provide concise object state information for debugging purposes.
  • Changed reservedSettingNames from List to HashSet in RemoteSessionSettings for potential performance improvement.

Changes walkthrough 📝

Relevant files
Enhancement
DriverOptions.cs
Add DebuggerDisplay for DriverOptions class                           

dotnet/src/webdriver/DriverOptions.cs

  • Added DebuggerDisplay attribute to DriverOptions class.
  • Implemented GetDebuggerDisplay method for concise object state
    representation.
  • +38/-0   
    ReturnedCapabilities.cs
    Add DebuggerDisplay for ReturnedCapabilities class             

    dotnet/src/webdriver/Internal/ReturnedCapabilities.cs

  • Added DebuggerDisplay attribute to ReturnedCapabilities class.
  • Implemented GetDebuggerDisplay method to show browser and capability
    count.
  • +12/-0   
    RemoteSessionSettings.cs
    Add DebuggerDisplay and optimize reservedSettingNames in
    RemoteSessionSettings

    dotnet/src/webdriver/Remote/RemoteSessionSettings.cs

  • Added DebuggerDisplay attribute to RemoteSessionSettings class.
  • Implemented GetDebuggerDisplay method for displaying browser and
    driver count.
  • Changed reservedSettingNames from List to HashSet.
  • +14/-1   

    💡 PR-Agent usage: Comment /help "your question" on any pull request to receive relevant information

    Copy link
    Contributor

    qodo-merge-pro bot commented Nov 9, 2024

    PR Reviewer Guide 🔍

    Here are some key observations to aid the review process:

    ⏱️ Estimated effort to review: 2 🔵🔵⚪⚪⚪
    🧪 No relevant tests
    🔒 No security concerns identified
    ⚡ Recommended focus areas for review

    Code Smell
    Trailing comma and space in the else branch return statement of GetDebuggerDisplay() method looks like a typo

    Performance
    Converting List to HashSet for reservedSettingNames may impact performance if Contains() is rarely called but items are frequently added

    Copy link
    Contributor

    qodo-merge-pro bot commented Nov 9, 2024

    PR Code Suggestions ✨

    Explore these optional code suggestions:

    CategorySuggestion                                                                                                                                    Score
    Possible bug
    ✅ Add null check to prevent potential null reference exception
    Suggestion Impact:The commit added a null check to mustMatchDriverOptions before accessing BrowserName, which aligns with the suggestion to prevent a potential NullReferenceException.

    code diff:

    -            string browser = this.mustMatchDriverOptions.BrowserName;
    +            string browser = this.mustMatchDriverOptions?.BrowserName;

    Add null check for mustMatchDriverOptions before accessing BrowserName to prevent
    potential NullReferenceException.

    dotnet/src/webdriver/Remote/RemoteSessionSettings.cs [358]

    -string browser = this.mustMatchDriverOptions.BrowserName;
    +string browser = this.mustMatchDriverOptions?.BrowserName;
    • Apply this suggestion
    Suggestion importance[1-10]: 9

    Why: Adding a null check is critical for preventing runtime NullReferenceException, as mustMatchDriverOptions could potentially be null. This is an important defensive programming practice.

    9
    Enhancement
    ✅ Remove unnecessary trailing characters in string formatting
    Suggestion Impact:The suggestion to remove the trailing comma and space in the return string of GetDebuggerDisplay() was implemented, improving code clarity.

    code diff:

    -            return $"Additional Driver Count = {this.firstMatchOptions.Count}, ";
    +            return $"Additional Driver Count = {this.firstMatchOptions.Count}";

    Remove the trailing comma and space in the fallback return string of
    GetDebuggerDisplay() as it creates unnecessary formatting.

    dotnet/src/webdriver/Remote/RemoteSessionSettings.cs [364]

    -return $"Additional Driver Count = {this.firstMatchOptions.Count}, ";
    +return $"Additional Driver Count = {this.firstMatchOptions.Count}";
    • Apply this suggestion
    Suggestion importance[1-10]: 7

    Why: The trailing comma and space in the debug display string serve no purpose and could be confusing. Removing them improves code clarity and correctness.

    7
    Performance
    Optimize StringBuilder initialization with capacity estimation

    Pre-calculate the initial StringBuilder capacity based on expected content length to
    reduce reallocations.

    dotnet/src/webdriver/DriverOptions.cs [633]

    -StringBuilder builder = new StringBuilder();
    +StringBuilder builder = new StringBuilder(64);
    • Apply this suggestion
    Suggestion importance[1-10]: 3

    Why: While pre-allocating StringBuilder capacity can improve performance by reducing reallocations, the impact here is minimal since the string being built is relatively small and this is debug-only code.

    3

    💡 Need additional feedback ? start a PR chat

    @nvborisenko
    Copy link
    Member

    Hi @RenderMichael , your statements are absolutely correct. But let me correct main goal: ToString() should not be involved in json serialization. If we can achieve it, then everything becomes clear. Because of using DebuggerDisplay attribute to avoid performance issues looks strange.

    @RenderMichael
    Copy link
    Contributor Author

    I wanted to be more careful, since changing a ToString() method is a breaking change. Even if Selenium doesn’t rely on it, maybe some users use it?

    Maybe the break is acceptable (it should be), but the debugger changes do not lead to any behavior differences at all.

    @nvborisenko
    Copy link
    Member

    I understand your motivation, but I don't like a way how it is achieved. We are mixing purposes for debugging, string representation and json serialization. It adds a complexity (which affects maintainability).

    If we would resolve initial issue with ToString(), then everything would clear.

    I am afraid I cannot accept this changes in context of "what and how we are trying to resolve it" - for me it is "workaround on top of workaround". Let's wait what others will say.

    @RenderMichael
    Copy link
    Contributor Author

    For what it’s worth, this debugger display is in line with what other custom debugger displays look like. For example, dictionaries look like this (and these types are basically strongly-typed dictionaries).

    I agree that without the heavy ToString(), these custom displays may not be necessary (I still like them) and the default {GetType().Name} would suffice.

    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.

    2 participants