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

Investigate async functionality #9

Closed
sco1 opened this issue Nov 2, 2023 · 2 comments
Closed

Investigate async functionality #9

sco1 opened this issue Nov 2, 2023 · 2 comments
Labels
deferred Will be considered at a later time internals Updates to things that aren't user-facing

Comments

@sco1
Copy link
Owner

sco1 commented Nov 2, 2023

Currently the main loop is just one task: checking OpenSky and then sleeping. I haven't checked yet but I'm assuming this sleep also blocks other functionality (e.g. touchscreen interaction), so will need to investigate how to accommodate this while keeping the refresh loop alive & on time.

@sco1 sco1 added the internals Updates to things that aren't user-facing label Nov 2, 2023
@sco1
Copy link
Owner Author

sco1 commented Nov 3, 2023

Trying to find an async way to make the web request to OpenSky seems like it will be a challenge, since the request library is not async & the asyncio library does not have run_in_executor. On average, a lot of time seems to be spent making this request (timeouts aren't uncommon), so unless it can be done in the background I think it's going to block any screen touching.

@sco1
Copy link
Owner Author

sco1 commented Nov 3, 2023

Gathering thoughts here as I go along so I don't have to keep going back and finding them. One suggestion from Discord is to chunk the response so other tasks can be run:

import random
import board
import wifi
import socketpool
import ssl
import neopixel
import asyncio
import adafruit_requests

# Choose your own URL adventure...
URL = "https://anecdata.dev/ada/chunked3/"

async def iter(req):
    while True:
        print(f"\nGET {URL}")
        with req.get(URL) as resp:
            print(resp.status_code, resp.reason.decode(), resp.headers)
            for c in resp.iter_content():
                print(f"{c.decode()}", end="")
                await asyncio.sleep(0)

async def pixel():
    with neopixel.NeoPixel(board.NEOPIXEL, 1) as pixels:
        while True:
            pixels.fill(random.randrange(0, 256*256*256))
            await asyncio.sleep(0.1)

async def main():
    iter_task = asyncio.create_task(iter(req))
    neo_task = asyncio.create_task(pixel())
    await asyncio.gather(iter_task, neo_task)

pool = socketpool.SocketPool(wifi.radio)
req = adafruit_requests.Session(pool, ssl.create_default_context())

asyncio.run(main())

This would need some adjusting since the PyPortal doesn't have wifi or socketpool modules. The PyPortal initializes a legacy session that takes care of this part of the setup. However, I don't think that chunking the response is going to be helpful here since the primary issue is the call to OpenSky timing out.

I'm thinking what might have to be done is replace the session itself. There is a PR drafted for an async session that may be able to be worked on to fit the bill.

@sco1 sco1 added the deferred Will be considered at a later time label Nov 10, 2023
@sco1 sco1 closed this as not planned Won't fix, can't repro, duplicate, stale Nov 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
deferred Will be considered at a later time internals Updates to things that aren't user-facing
Projects
None yet
Development

No branches or pull requests

1 participant