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: allow address reuseage on socket binding #35

Merged
merged 1 commit into from
Feb 7, 2023
Merged

Conversation

firstof9
Copy link
Owner

@firstof9 firstof9 commented Feb 2, 2023

may or may not fix [Errno 98] Address in use errors.

@firstof9 firstof9 merged commit 6ad4a6b into master Feb 7, 2023
@firstof9 firstof9 deleted the add-reuseaddr branch February 7, 2023 13:30
@lyricnz
Copy link
Collaborator

lyricnz commented Feb 7, 2023

I don't think this fixes the issue (at least on my PC): if I add await asyncio.sleep(1) to the middle of TpLinkESS.query() to make it slow enough to be repeatably concurrent, then run >1 at the same time:

    async def run_query(switch, op_code):
        logging.info("Querying %s for %s", switch["hostname"], op_code)
        switch[op_code] = await x.query(switch["mac"], op_code)
        logging.info("Querying DONE %s for %s", switch["hostname"], op_code)

    for switch in switches:
        logging.info("Querying %s", switch["hostname"])
        tasks.append(run_query(switch, "stats"))
        tasks.append(run_query(switch, "ports"))
        tasks.append(run_query(switch, "vlan"))

I still get the error:

2023-02-08 09:11:28,097 INFO     Querying TL-SG108E for ports
2023-02-08 09:11:28,098 INFO     Querying TL-SG108E for vlan
2023-02-08 09:11:28,098 INFO     Querying Simon-TL-SG105PE for stats
2023-02-08 09:11:28,098 INFO     Querying Simon-TL-SG105PE for ports
2023-02-08 09:11:28,098 INFO     Querying Simon-TL-SG105PE for vlan
2023-02-08 09:11:28,099 INFO     Querying Back-TL-SG105PE for stats
2023-02-08 09:11:28,099 INFO     Querying Back-TL-SG105PE for ports
2023-02-08 09:11:28,099 INFO     Querying Back-TL-SG105PE for vlan
Traceback (most recent call last):
  File "/Users/simonroberts/src/github/firstof9/tplink-ess-lib/tplink_ess_lib/network.py", line 56, in __init__
    self.r_socket.bind((Network.BROADCAST_ADDR, Network.UDP_RECEIVE_FROM_PORT))
OSError: [Errno 49] Can't assign requested address

During handling of the above exception, another exception occurred:
...
  File "/Users/simonroberts/src/github/firstof9/tplink-ess-lib/tplink_ess_lib/network.py", line 58, in __init__
    self.r_socket.bind(("", Network.UDP_RECEIVE_FROM_PORT))
OSError: [Errno 48] Address already in use

@lyricnz
Copy link
Collaborator

lyricnz commented Feb 7, 2023

Also, fundamentally we can't do this concurrently (unless we use dynamic listen ports). Since the socket-reader consumes all packets (even if they're not intended for the current query/response) this will cause timeouts for other operations.

@firstof9
Copy link
Owner Author

firstof9 commented Feb 7, 2023

Maybe a loop with a sleep until it can grab the port?

@lyricnz
Copy link
Collaborator

lyricnz commented Feb 7, 2023

Brutal, but would work. Would still need a retry/timeout to prevent lockup if "strange things happen". We already have a context manager to make sure the socket is closed.

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