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

Initial version #2

Merged
merged 14 commits into from
Oct 16, 2023
Merged

Initial version #2

merged 14 commits into from
Oct 16, 2023

Conversation

emontnemery
Copy link
Collaborator

Initial version of the library

improv_ble/improv_ble_client.py Outdated Show resolved Hide resolved
improv_ble/improv_ble_client.py Outdated Show resolved Hide resolved
improv_ble/improv_ble_client.py Outdated Show resolved Hide resolved
improv_ble/improv_ble_client.py Outdated Show resolved Hide resolved
improv_ble/improv_ble_client.py Outdated Show resolved Hide resolved
return_when=asyncio.FIRST_COMPLETED,
)
for task in pending:
task.cancel()
Copy link
Member

Choose a reason for hiding this comment

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

This might complain about an unretrieved exception if it's not awaited

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The variable name is misleading, these are futures, not tasks.
I think the potential error here is if the cancelled futures have their result set after we cancel them?

Copy link
Member

Choose a reason for hiding this comment

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

I think the potential error here is if the cancelled futures have their result set after we cancel them?

That is a risk if you await them as they will propagate cancelation from the point of await

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

As discussed on Discord the code is fine, but the variable names are misleading and unclear. I'll clean it up.


_LOGGER.debug(
"%s: Subscribe to notifications; RSSI: %s", self.name, self.rssi
)
Copy link
Member

@bdraco bdraco Oct 13, 2023

Choose a reason for hiding this comment

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

Maybe verify all the char uuids are present and if not try clearing the cache and reconnecting to the device so the services get resolved again.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Can you link to an example doing that?

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Collaborator Author

@emontnemery emontnemery Oct 16, 2023

Choose a reason for hiding this comment

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

I see, that's more or less a workaround for a missing feature in bleak IMHO, and the same implementation is duplicated in multiple BLE-packages: eulife_ble_client, ld2410_ble, led_ble, switchbot.

Maybe it could be moved to its own package, bleak_utils or bleak_helpers?
I'll copy the implementation to py-improv-ble for now though.

Copy link
Member

Choose a reason for hiding this comment

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

I'm happy to accept a PR to bleak_retry_connector

error_fut: asyncio.Future[prot.Error] = asyncio.Future()
provisioned_fut = self.receive_response(prot.WiFiSettingsRes)

try:
Copy link
Member

Choose a reason for hiding this comment

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

Does this need a timeout? I may be easier to handle cancelation inside the inner functions on timeout if you limit the scope of the timeout to this function

Copy link
Collaborator Author

@emontnemery emontnemery Oct 14, 2023

Choose a reason for hiding this comment

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

To not simplify things I chose to only have a single global timeout, handled by the ImprovBLEClient._disconnect_timer.
Could you give an example of how cancellation could be simplified if the timeout scope is narrowed?

Copy link
Member

Choose a reason for hiding this comment

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

You have to make sure all the code running under the timeout is cancellation safe (ie cleans up and disconnects ok if it gets canceled)

By limiting the scope of where we expect cancellation to happen to just the area where its going to timeout thats a bit easier, but its also better to have all the code handle cancellation

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Right, I prefer to handle the the cancellation at one place higher up instead of in several places further down.

Copy link
Member

Choose a reason for hiding this comment

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

Its probably safe since there is a disconnect timer that won't be canceled when the task is cancelled.

Maybe it would be good to add a test to make sure if any operation is cancelled by the task its running in being canceled, it still disconnects.

improv_ble_client/protocol.py Outdated Show resolved Hide resolved
improv_ble_client/protocol.py Show resolved Hide resolved
Comment on lines 390 to 392
disconnect_task = asyncio.create_task(_disconnect())
self._background_tasks.add(disconnect_task)
disconnect_task.add_done_callback(self._background_tasks.discard)
Copy link
Member

Choose a reason for hiding this comment

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

This could be self._async_create_background_task() since you have the same pattern in _disconnect

@bdraco
Copy link
Member

bdraco commented Oct 16, 2023

One small comment above, and some lint issues, but otherwise LGTM 👍

@emontnemery emontnemery merged commit 645b592 into main Oct 16, 2023
1 check passed
@emontnemery emontnemery deleted the initial_version branch October 16, 2023 18:14
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.

3 participants