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 issue with late published prices #333

Conversation

viiru-
Copy link

@viiru- viiru- commented Jul 4, 2023

  • Limit backoff and maximum time to retry for AioPrices.fetch()
  • Add constant to hold invalid values and use instead of repeating
  • Move tomorrow_valid functionality to NordpoolData
  • Only send EVENT_NEW_PRICE signal if new data is available
  • Retry polling for new data hourly if needed

Fixes #326

@Hellowlol
Copy link
Collaborator

Hi,

Thanks for the PR. Have you tested the changes? I suspect this will generate a lot of retries and we attempt to validate every value, even the ones we don’t need or want.

@viiru-
Copy link
Author

viiru- commented Jul 4, 2023

Thanks for the PR. Have you tested the changes? I suspect this will generate a lot of retries and we attempt to validate every value, even the ones we don’t need or want.

I have tested it by running this at different times of the day (both before and after the prices are published):

dt = datetime.now() + timedelta(days=1)
async with aiohttp.ClientSession() as session:
    spot = AioPrices('EUR', session)
    data = await spot.hourly(end_date=dt)

I haven't really looked at the number of retries produced. Probably in the beginning of the exponential backoff it retries needlessly often but that doesn't appear to be configurable in the retry/backoff implementation being used.

@Hellowlol
Copy link
Collaborator

Ok, please check. I assume is will retry until it succeeds, however it should not do that if we know it going to fail. Example: user restart or reloads integration at 0700 the integration will have issues getting the integration to work as it fails for tomorrows request because the prices and None because they are not available. The integration fails to be setup as it takes on longer than 10 minutes.

@viiru-
Copy link
Author

viiru- commented Jul 4, 2023

Ok, please check. I assume is will retry until it succeeds, however it should not do that if we know it going to fail. Example: user restart or reloads integration at 0700 the integration will have issues getting the integration to work as it fails for tomorrows request because the prices and None because they are not available. The integration fails to be setup as it takes on longer than 10 minutes.

Right. I understand the problem. update_tomorrow() is called by both _someday (unnecessarily if only today is requested) which must be allowed to fail and also by new_data_cb() which must not. Adding and passing along a parameter would make things quite a bit more ugly.

Perhaps the right choice is instead to move the tomorrow_valid check to common code and run that before sending EVENT_NEW_PRICE (as this issue is caused by sending that without having valid data available)? However needing to make new_data_cb() retry itself is pretty nasty.

While reading this code I keep having the feeling of painting oneself into a corner and then applying endless workarounds to desperately try to paint back out...

@Hellowlol
Copy link
Collaborator

Yeah, it quickly get more complicated what you could do it to move the check after we check I’d the start and end is the same than add additional check that checks the time, it’s it less than renewal time and the call is for tomorrow ignore and raise the error is it’s today or tomorrow after the prices should be available.

You can see a example in #127

@Hellowlol
Copy link
Collaborator

I can do a proper review after my vacation ends. I have only checked on mobile.

@viiru-
Copy link
Author

viiru- commented Jul 4, 2023

I'm currently thinking of the following:

  1. remove new_data_cb()
  2. add tomorrow_valid to NordPoolData
  3. run the update from new_hr() if not tomorrow_valid and time after 13:RANDOM_MINUTE
  4. after the update check tomorrow_valid again and signal if valid data was received

With those changes the component would end up retrying every hour until valid data appears. A simpler alternative would be to just poll every hour or so and just ignore the time when the auction usually finishes.

In any case the important thing is to not advertise what the aptly named add_junk() function created as valid data.

@viiru- viiru- force-pushed the fix-issue-with-late-published-prices branch 6 times, most recently from 9b47c04 to 6277684 Compare July 6, 2023 12:19
@viiru- viiru- force-pushed the fix-issue-with-late-published-prices branch 5 times, most recently from 12a6cd6 to b05d7b3 Compare July 9, 2023 05:20
@viiru-
Copy link
Author

viiru- commented Jul 9, 2023

@yozik04 I believe this is now "ready" in that it works and the tdo stuff has been cleaned up. Can you review again?

Copy link

@yozik04 yozik04 left a comment

Choose a reason for hiding this comment

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

Looks good to me.


async def tomorrow(self, area: str, currency: str):
"""Returns tomorrow's prices in an area in the requested currency"""
return await self._someday(area, currency, "tomorrow")


def tomorrow_valid(self, area: str, currency: str) -> bool:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you move all the validation to aio_price? I would prefer to do it there, this allows for easier testing.

Copy link
Author

Choose a reason for hiding this comment

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

That is indeed what I initially tried to do, before you explained to me why what I was doing isn't possible.

Since AioPrices doesn't keep a copy of the data (it only retrieves it, the result is stored by NordpoolData) the approach I ended up with doesn't work there.

A combination of the two variants I have so far attempted is probably possible by having AioPrices raise an exception on invalid data and handling that exception in NordpoolData (instead of having AioPrices retry like I had previously).

Copy link
Author

Choose a reason for hiding this comment

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

I have now tested and pushed an implementation of that idea.

Arto Jantunen added 5 commits July 26, 2023 17:11
Infinite backoff and retry is a rather strange configuration..
This seems like a vestigial leftover from an earlier
implementation (probably where these functions were called directly by
listeners).
This happens if the first auction is unsuccessful.

Implemented by verifying that the data is valid (in
join_result_for_correct_time()) and raising an exception if it isn't.

This partially fixes issue custom-components#326.
Data for tomorrow may or may not be available when initializing the
component.
Using the already-used-elsewhere backoff library. Retry every 10 minutes
for a maximum of two hours.
@viiru- viiru- force-pushed the fix-issue-with-late-published-prices branch from b05d7b3 to 944b434 Compare August 4, 2023 11:37
@Hellowlol
Copy link
Collaborator

Looks good, I havnt had time to test it yet. Ill create a beta branch so people can test it

@Hellowlol Hellowlol merged commit 9bfcc5f into custom-components:master Aug 8, 2023
3 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.

Version 0.0.14 does not load tomorrow’s prices
3 participants