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

common: general improvements #713

Merged
merged 2 commits into from
Feb 3, 2025

Conversation

dougsland
Copy link
Collaborator

@dougsland dougsland commented Feb 3, 2025

  • if timeout happens we try 5 times before sending Timeout error to users.

  • improve user experience when timeout occurs

  • Added console source tree for handling messages

Resolves: #693

Summary by Sourcery

Improve the reliability of file downloads and introduce logging with user-friendly messages.

Bug Fixes:

  • Retry file downloads up to five times if a timeout or network error occurs.

Enhancements:

  • Added logging for network errors, timeouts, and other download-related issues.
  • Improved user experience by providing more informative messages during file downloads.

Copy link
Contributor

sourcery-ai bot commented Feb 3, 2025

Reviewer's Guide by Sourcery

This pull request introduces several improvements to the download process, including retries with exponential backoff, enhanced error messages, and the addition of a console module for consistent output formatting.

Sequence diagram for improved file download process with retries

sequenceDiagram
    participant C as Client
    participant D as download_file
    participant H as HttpClient
    participant S as Server

    C->>D: download_file(url, dest_path)
    activate D

    loop max_retries (5 times)
        D->>H: init(url, headers, output_file)
        activate H
        H->>S: HTTP Request

        alt Success
            S-->>H: File Data
            H-->>D: Success
            D-->>C: Return
        else HTTP 416 (Range Not Satisfiable)
            S-->>H: 416 Error
            H-->>D: Already downloaded
            D-->>C: Return
        else Network/Timeout Error
            S-->>H: Error/Timeout
            H-->>D: Error
            D->>D: Wait (exponential backoff)
            Note over D: Retry if attempts < 5
        end

        deactivate H
    end

    alt Max retries reached
        D-->>C: Exit with error message
    end

    deactivate D
Loading

Class diagram for new console module

classDiagram
    class console {
        +bool EMOJI
        +bool FORCE_EMOJI
        +is_locale_utf8()
        +supports_emoji()
        +error(msg)
        +warning(msg)
        +info(msg)
    }

    note for console "New module for consistent
formatted console output
with emoji support"
Loading

Flow diagram for emoji support detection

flowchart TD
    A[Check emoji support] --> B{RAMALAMA_FORCE_EMOJI set?}
    B -->|Yes| C{Value is 'true'?}
    C -->|Yes| D[Enable emoji]
    C -->|No| E[Disable emoji]
    B -->|No| F{Check TERM env}
    F -->|dumb/linux| E
    F -->|other| G{Check UTF-8 locale}
    G -->|Yes| D
    G -->|No| E
Loading

File-Level Changes

Change Details Files
Implement retries with exponential backoff for file downloads.
  • Added a retry mechanism for download failures.
  • Implemented exponential backoff for retries.
  • Limited the number of retries to 5.
  • Improved error handling for network issues, timeouts, and I/O errors.
  • Added a generic exception handler to catch unexpected errors.
  • Added a message to the user when the download fails after multiple attempts.
ramalama/common.py
Improve user experience by providing more informative error messages.
  • Added a console module for handling messages.
  • Added error, warning, and info functions to the console module.
  • Added emoji support to the console module.
  • Replaced print statements with console module functions.
  • Added more descriptive error messages for download failures.
ramalama/common.py
ramalama/console.py
Added a new console module for handling messages.
  • Added a new console module.
  • Added functions for error, warning, and info messages.
  • Added emoji support to the console module.
  • Added a check for UTF-8 locale to enable emoji support.
ramalama/console.py
Added console.py to the list of files to install.
  • Added console.py to the list of files to install.
install.sh

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!
  • Generate a plan of action for an issue: Comment @sourcery-ai plan on
    an issue to generate a plan of action for it.

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@dougsland
Copy link
Collaborator Author

I believe the code is ready for review this time. Please let me know if I missed something.

- if timeout happens we try 5 times before
  sending Timeout error to users.

- improve user experience when timeout occurs

- Added console source tree for handling messages

Resolves: containers#693
Signed-off-by: Douglas Schilling Landgraf <[email protected]>
import logging


def is_locale_utf8():
Copy link
Collaborator

@ericcurtin ericcurtin Feb 3, 2025

Choose a reason for hiding this comment

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

I tested this on macOS with alacritty it needs one more check to work, because this is the only env var (LC_ALL) of the 3 env vars populated on this platform:

 $ echo $LC_ALL
 en_IE.UTF-8

So we need to add one more or:

return 'UTF-8' in os.getenv('LC_CTYPE', '') or 'UTF-8' in os.getenv('LANG', '') or 'UTF-8' in os.getenv('LC_ALL', '')

Copy link
Collaborator

@ericcurtin ericcurtin Feb 3, 2025

Choose a reason for hiding this comment

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

Could also do:

return any('UTF-8' in os.getenv(var, '') for var in ['LC_CTYPE', 'LANG', 'LC_ALL'])

to be less long-winded, as long as it works I don't mind too much. And it just checks these three env vars for UTF-8, I don't care after that point.

# If RAMALAMA_FORCE_EMOJI is not set, it defaults to checking supports_emoji()
RAMALAMA_FORCE_EMOJI = os.getenv("RAMALAMA_FORCE_EMOJI")
FORCE_EMOJI = RAMALAMA_FORCE_EMOJI.lower() == "true" if RAMALAMA_FORCE_EMOJI else None
EMOJI = FORCE_EMOJI if FORCE_EMOJI is not None else supports_emoji()
Copy link
Collaborator

@ericcurtin ericcurtin Feb 3, 2025

Choose a reason for hiding this comment

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

Lines 21-23 are long-winded it took me a while to read this and try and understand if it was correct, lets simplify:

EMOJI = os.getenv("RAMALAMA_FORCE_EMOJI") or supports_emoji()

Make lint is a good one to have.

Signed-off-by: Douglas Schilling Landgraf <[email protected]>
@ericcurtin
Copy link
Collaborator

This PR is much easier to review, a much more focused PR. I think we are close.



# Define emoji-aware logging messages
def error(msg):
Copy link
Collaborator

@ericcurtin ericcurtin Feb 3, 2025

Choose a reason for hiding this comment

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

The spacing isn't consistent in the printed output in these three functions, some are double-space some are single-space.

If you are pushing new commits you might as well catch it here, we can also do in a follow on PR.

@ericcurtin
Copy link
Collaborator

I'll catch the changes in another PR I have the time

@ericcurtin ericcurtin merged commit 6706b26 into containers:main Feb 3, 2025
11 of 12 checks passed
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.

(Timeout download model): python3.13/ssl.py", line 1138, in read return self._sslobj.read(len, buffer)
2 participants