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 Windows NotImplementedError / Hanging of program #147

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

ziloka
Copy link

@ziloka ziloka commented Nov 13, 2023

The ProxyBroker program will hang when the find command (at least, the only thing tested) is executed.

This PR allows proxybroker to be used on python 3.11.0 and returns some output.

3.12.0 does not work due to not being able to compile aiohttp not supporting 3.12

Summary by CodeRabbit

  • Refactor
    • Enhanced event loop handling for better compatibility with Windows systems, including setting platform-specific policies and explicitly creating new event loops in multiple components and scripts.

Copy link

sweep-ai bot commented Nov 13, 2023

Apply Sweep Rules to your PR?

  • Apply: All new business logic should have corresponding unit tests.
  • Apply: Refactor large functions to be more modular.

@bluet
Copy link
Owner

bluet commented Dec 5, 2023

@ziloka awesome.
I see tests failed because they were testing aiodns. Would you mind update those tests to dnspython too?
BTW, can also add 3.11.0 into CI test python version. 😃

@bluet
Copy link
Owner

bluet commented Dec 6, 2023

Relate to #113

@ziloka
Copy link
Author

ziloka commented Dec 9, 2023

I need to add a fix .

I don't think this works just yet, sorry

@ziloka ziloka marked this pull request as draft December 9, 2023 20:11
@ziloka
Copy link
Author

ziloka commented Jan 17, 2024

The program stops hanging but it is slow.

Python 3.11 and python 3.12 will work but it will have (deprecation?) warnings about Transport Sockets.

Note that I only tested the find command

@ziloka
Copy link
Author

ziloka commented Jan 17, 2024

I am unable to convert this into a "ready" pull request

@ziloka
Copy link
Author

ziloka commented Jan 18, 2024

We might want to look into this issue
aiortc/aioquic#289

Copy link

sonarcloud bot commented Jan 18, 2024

Quality Gate Failed Quality Gate failed

Failed conditions

16.0% Duplication on New Code (required ≤ 3%)

See analysis details on SonarCloud

@ziloka ziloka mentioned this pull request Jan 19, 2024
@ziloka
Copy link
Author

ziloka commented Jan 19, 2024

This pull request does not resolve the serve issue.

To fix that issue, I believe it is necessary to migrate from asyncio to trio.
See this stackoverflow comment for my reasons.
An additional reason is that the examples need to be updated and it would be inconvenient and unnecessary for applications who use this upstream to put

if sys.platform == 'win32':
    asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())

In their code.

I would like to know the other maintainer's thoughts before making a merge for this.

Copy link

coderabbitai bot commented Mar 18, 2024

Walkthrough

The overarching modification across the updated files involves enhancing the handling and initialization of the asyncio event loop, particularly focusing on compatibility with Windows systems. This is achieved by explicitly importing the sys module, setting the event loop policy for Windows, creating new event loops, and passing these loops directly to constructors without relying on default event loop retrieval methods. These changes streamline event loop management and ensure more reliable operation across different platforms.

Changes

Files Change Summary
examples/basic.py, examples/find_and_save.py, examples/find_and_use.py, examples/only_grab.py, examples/proxy_server.py, examples/proxy_smtp_port.py, examples/use_existing_proxy.py Added sys import, set event loop policy for Windows, explicitly created and set new event loops, passed event loop to Broker constructor.
proxybroker/api.py, proxybroker/checker.py, proxybroker/cli.py, proxybroker/judge.py, proxybroker/providers.py, proxybroker/resolver.py, proxybroker/server.py Modified event loop initialization and handling: directly assigned loop parameter, removed default assignment or fallback to asyncio.get_event_loop().

🐰✨
Changes abound, both near and far,
In code where async streams do flow.
A rabbit hopped, beneath a star,
To fix the loops and make them glow.
🌟🔄
With every hop, a bug did flee,
And Windows found a friend in thee.
🐰✨

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-tests 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 tests 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 tests.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

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 a review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai help to get help.

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

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • The JSON schema for the configuration file is available here.
  • 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/coderabbit-overrides.v2.json

CodeRabbit Discord Community

Join our Discord Community to get help, request features, and share feedback.

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.

Review Status

Actionable comments generated: 2

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 928f4aa and b4d5404.
Files selected for processing (14)
  • examples/basic.py (2 hunks)
  • examples/find_and_save.py (2 hunks)
  • examples/find_and_use.py (3 hunks)
  • examples/only_grab.py (2 hunks)
  • examples/proxy_server.py (2 hunks)
  • examples/proxy_smtp_port.py (3 hunks)
  • examples/use_existing_proxy.py (2 hunks)
  • proxybroker/api.py (1 hunks)
  • proxybroker/checker.py (1 hunks)
  • proxybroker/cli.py (1 hunks)
  • proxybroker/judge.py (1 hunks)
  • proxybroker/providers.py (1 hunks)
  • proxybroker/resolver.py (1 hunks)
  • proxybroker/server.py (2 hunks)
Files not reviewed due to errors (1)
  • (no review received)
Additional comments: 32
examples/basic.py (4)
  • 3-3: Importing sys is necessary for checking the platform. This change is appropriate for the intended compatibility improvements.
  • 16-17: Setting the event loop policy for Windows is a critical change for compatibility with Python 3.11.0 on Windows platforms. This ensures that the WindowsSelectorEventLoopPolicy is used, which is necessary for the program to function correctly on Windows.
  • 19-20: Creating and setting a new event loop is essential for ensuring that the asyncio operations use the correct event loop, especially after setting the event loop policy for Windows. This change is consistent with the goal of enhancing compatibility.
  • 23-23: Passing the newly created event loop to the Broker constructor is a necessary step to ensure that all asynchronous operations within the Broker use the correct event loop. This change aligns with the modifications made for event loop management.
examples/only_grab.py (4)
  • 4-4: The import of sys is necessary for platform checking, which is crucial for the compatibility improvements aimed at Windows platforms.
  • 9-10: Setting the event loop policy for Windows with WindowsSelectorEventLoopPolicy is essential for compatibility with Python 3.11.0 on Windows. This change is consistent with the overall goal of the PR.
  • 23-24: Creating and setting a new event loop ensures that the asyncio operations use the correct event loop, especially important after setting the event loop policy for Windows. This is a necessary change for the intended compatibility improvements.
  • 27-27: Passing the newly created event loop to the Broker constructor ensures that all asynchronous operations within the Broker use the correct event loop. This change is consistent with the modifications made for event loop management.
examples/find_and_save.py (4)
  • 3-3: Importing sys for platform checking is appropriate and necessary for the compatibility improvements with Windows platforms.
  • 8-9: Setting the event loop policy for Windows is crucial for ensuring compatibility with Python 3.11.0 on Windows. This change is aligned with the PR's objectives.
  • 24-25: Creating and setting a new event loop is essential for the correct functioning of asyncio operations, especially after setting the event loop policy for Windows. This change supports the intended compatibility improvements.
  • 27-27: Passing the newly created event loop to the Broker constructor is necessary to ensure that all asynchronous operations within the Broker use the correct event loop. This is consistent with the event loop management modifications.
examples/proxy_smtp_port.py (4)
  • 4-4: Importing sys for platform checking is necessary for the compatibility improvements aimed at Windows platforms. This change is appropriate.
  • 9-10: Setting the event loop policy for Windows with WindowsSelectorEventLoopPolicy is essential for compatibility with Python 3.11.0 on Windows. This change is consistent with the PR's objectives.
  • 23-24: Creating and setting a new event loop ensures that the asyncio operations use the correct event loop, especially important after setting the event loop policy for Windows. This is a necessary change for the intended compatibility improvements.
  • 26-26: Passing the newly created event loop to the Broker constructor ensures that all asynchronous operations within the Broker use the correct event loop. This change is consistent with the modifications made for event loop management.
examples/use_existing_proxy.py (3)
  • 4-4: The import of sys is necessary for platform checking, which is crucial for the compatibility improvements aimed at Windows platforms.
  • 9-10: Setting the event loop policy for Windows with WindowsSelectorEventLoopPolicy is essential for compatibility with Python 3.11.0 on Windows. This change is consistent with the overall goal of the PR.
  • 39-40: Creating and setting a new event loop ensures that the asyncio operations use the correct event loop, especially important after setting the event loop policy for Windows. This is a necessary change for the intended compatibility improvements.
examples/proxy_server.py (3)
  • 4-4: Importing sys for platform checking is necessary for the compatibility improvements aimed at Windows platforms. This change is appropriate.
  • 11-12: Setting the event loop policy for Windows with WindowsSelectorEventLoopPolicy is essential for compatibility with Python 3.11.0 on Windows. This change is consistent with the PR's objectives.
  • 41-42: Creating and setting a new event loop ensures that the asyncio operations use the correct event loop, especially important after setting the event loop policy for Windows. This is a necessary change for the intended compatibility improvements.
examples/find_and_use.py (3)
  • 7-7: The import of sys is necessary for platform checking, which is crucial for the compatibility improvements aimed at Windows platforms.
  • 16-17: Setting the event loop policy for Windows with WindowsSelectorEventLoopPolicy is essential for compatibility with Python 3.11.0 on Windows. This change is consistent with the overall goal of the PR.
  • 53-54: Creating and setting a new event loop ensures that the asyncio operations use the correct event loop, especially important after setting the event loop policy for Windows. This is a necessary change for the intended compatibility improvements.
proxybroker/resolver.py (1)
  • 47-47: The modification to explicitly set the _loop attribute from the passed loop parameter, without defaulting to asyncio.get_event_loop(), is a positive change. It aligns with the PR's objective to manage event loops more explicitly, which is crucial for compatibility with Windows and newer Python versions. This approach ensures that the Resolver class uses the event loop that is explicitly passed to it, providing a more controlled way of handling event loops across the application.
proxybroker/checker.py (1)
  • 46-46: The modification to explicitly set the _loop attribute from the passed loop parameter, without defaulting to asyncio.get_event_loop(), is consistent with the changes in other parts of the application and aligns with the PR's objective to manage event loops more explicitly. This approach ensures that the Checker class uses the event loop that is explicitly passed to it, contributing to a more controlled and consistent way of handling event loops across the application, especially important for compatibility with Windows and newer Python versions.
proxybroker/cli.py (1)
  • 390-391: The changes to explicitly create and set the event loop using asyncio.new_event_loop() and asyncio.set_event_loop(loop) in the cli function are positive and align with the PR's objective to manage event loops more explicitly. This approach ensures that the cli function uses a specific event loop that is compatible with the rest of the application's event loop management strategy, which is crucial for compatibility with Windows and newer Python versions.
proxybroker/server.py (2)
  • 134-134: The modification to explicitly set the _loop attribute from the passed loop parameter, without defaulting to asyncio.get_event_loop(), in the Server class is a positive change. It aligns with the PR's objective to manage event loops more explicitly, ensuring that the Server class uses the event loop that is explicitly passed to it. This approach contributes to a more controlled and consistent way of handling event loops across the application, especially important for compatibility with Windows and newer Python versions.
  • 154-154: Removing the loop parameter from the start_server call in the start method of the Server class aligns with the changes made to explicitly manage event loops within the application. This ensures consistency in how event loops are handled and is crucial for compatibility with Windows and newer Python versions.
proxybroker/providers.py (2)
  • 48-48: Given the change to explicitly require an event loop when instantiating Provider, it's crucial to thoroughly test and validate the impact on asynchronous operations throughout the codebase. This includes ensuring that the event loop is correctly passed and managed in all asynchronous contexts where Provider or its subclasses are used.

Ensure comprehensive testing, especially on Windows platforms with Python 3.11.0, to verify that the change does not introduce regressions or negatively affect performance. Consider adding unit tests that cover various scenarios of event loop management and usage.

  • 48-48: To support users in adapting to the change in event loop management, consider enhancing documentation to clearly explain the need to explicitly pass an event loop when using Provider. Additionally, robust error handling for cases where an event loop is not provided can help prevent common issues and improve the user experience. Finally, consider backward compatibility strategies to ease the transition for existing users of the library.
  • Enhance documentation to cover the change in event loop management.
  • Implement robust error handling for missing event loop arguments.
  • Consider backward compatibility strategies to support existing users.

proxybroker/api.py Outdated Show resolved Hide resolved
proxybroker/providers.py Show resolved Hide resolved
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Copy link

sonarcloud bot commented Mar 25, 2024

Quality Gate Failed Quality Gate failed

Failed conditions
16.0% Duplication on New Code (required ≤ 3%)

See analysis details on SonarCloud

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.

Review Status

Actionable comments generated: 0

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between b4d5404 and 26fa1de.
Files selected for processing (1)
  • proxybroker/api.py (1 hunks)
Additional comments: 1
proxybroker/api.py (1)
  • 67-67: The update to the _loop variable initialization using conditional assignment is a good practice for managing event loops in asyncio-based applications. It ensures flexibility and compatibility across different environments.

However, it's important to verify the impact of this change on the overall functionality and compatibility of the ProxyBroker program, especially considering the PR's objectives to address compatibility issues with newer Python versions on Windows.

Verification successful

The verification process has confirmed that the change to the _loop variable initialization in the Broker class is well-integrated across the codebase. The instances of the Broker class being instantiated with an explicitly passed loop parameter in various parts of the codebase align with the updated logic to allow for a default event loop when none is provided. This ensures flexibility and compatibility across different environments, aligning with the objectives of the PR to address compatibility issues with newer Python versions on Windows.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Verify that the Broker class is correctly utilized across the codebase with the updated event loop initialization logic.
rg --type py "Broker("

# Ensure that there are no direct calls to asyncio.get_event_loop() that might conflict with the Broker class's event loop management.
rg --type py "asyncio.get_event_loop()" --context 2

Length of output: 1046



Script:

#!/bin/bash
# Correct the regex error and verify the Broker class is correctly utilized across the codebase with the updated event loop initialization logic.
rg --type py "Broker\("

# No need to rerun the search for asyncio.get_event_loop() as it has already been successfully executed.

Length of output: 477

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