Skip to content

Avoid creating multiple sqlalchemy sessions in a single history call #35721

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

Merged
merged 4 commits into from
May 19, 2020

Conversation

bdraco
Copy link
Member

@bdraco bdraco commented May 17, 2020

Note: this is easier to review with git diff -w upstream/dev -- homeassistant/components/history

Breaking change

The history function states_to_json is now a protected function _states_to_json and is not expected to be called from outside the module.

Not sure if this is a breaking change since there were no outside callers in the codebase.

Proposed change

Ensure there is only one sqlalchemy session created per history query.

Functionality should be exactly the same otherwise as the changes
are rearranging and breaking apart functions only to avoid the multiple
sessions.

Most history queries created three sqlalchemy sessions which was
especially slow with sqlite since it opens and closes the
database.

In testing the UI is noticeably faster at generating history
graphs for entities.

Requires #35716

Testing: strace home assistant and verified the sqlite database was only opened and closed once per history api request instead of 3 times.

Type of change

  • Dependency upgrade
  • Bugfix (non-breaking change which fixes an issue)
  • New integration (thank you!)
  • New feature (which adds functionality to an existing integration)
  • Breaking change (fix/feature causing existing functionality to break)
  • Code quality improvements to existing code or addition of tests

Example entry for configuration.yaml:

# Example configuration.yaml

Additional information

  • This PR fixes or closes issue: fixes #
  • This PR is related to issue:
  • Link to documentation pull request:

Checklist

  • The code change is tested and works locally.
  • Local tests pass. Your PR cannot be merged unless tests pass
  • There is no commented out code in this PR.
  • I have followed the development checklist
  • The code has been formatted using Black (black --fast homeassistant tests)
  • Tests have been added to verify that the new code works.

If user exposed functionality or configuration variables are added/changed:

If the code communicates with devices, web services, or third-party tools:

  • The manifest file has all fields filled out correctly.
    Updated and included derived files by running: python3 -m script.hassfest.
  • New or updated dependencies have been added to requirements_all.txt.
    Updated by running python3 -m script.gen_requirements_all.
  • Untested files have been added to .coveragerc.

The integration reached or maintains the following Integration Quality Scale:

  • No score or internal
  • 🥈 Silver
  • 🥇 Gold
  • 🏆 Platinum

@bdraco bdraco force-pushed the one_session_scope_history branch 2 times, most recently from 50ab34d to 4c9e3c6 Compare May 17, 2020 03:03
@bdraco bdraco marked this pull request as ready for review May 17, 2020 05:09
@elupus
Copy link
Contributor

elupus commented May 17, 2020

Nice!

For a separate pull, maybe keeping a pool of sessions that are delay-closed. So that when a request comes in, there is always a free session to use. Would reduce latency of the call.

@bdraco
Copy link
Member Author

bdraco commented May 17, 2020

Nice!

For a separate pull, maybe keeping a pool of sessions that are delay-closed. So that when a request comes in, there is always a free session to use. Would reduce latency of the call.

I believe that is already the default for mysql/pgsql/etc. sqlite is defaulting to NullPool but should be able to use QueuePool if compiled with threadsafety. All the open/close is probably another thing that eats SD cards for lunch.

@bdraco
Copy link
Member Author

bdraco commented May 17, 2020

Nice!

For a separate pull, maybe keeping a pool of sessions that are delay-closed.

Done in #35754

bdraco added 3 commits May 18, 2020 16:59
The history api was creating a job to fetch the
states and another job to convert the states to
json. This can be done in a single job which
decreases the overhead of the operation.
query.

Most queries created three sqlalchemy sessions which was
especially slow with sqlite since it opens and closes the
database.

In testing the UI is noticeably faster at generating history
graphs for entites.
@bdraco bdraco force-pushed the one_session_scope_history branch from bc655a7 to 92d6ac0 Compare May 18, 2020 17:01
Copy link
Contributor

@elupus elupus left a comment

Choose a reason for hiding this comment

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

From my perspective this looks good. A tip for reviewer, you can skip whitespace changes in github as well via the gear ⚙️button on the top of the review page.

Copy link
Member

@MartinHjelmare MartinHjelmare left a comment

Choose a reason for hiding this comment

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

I'm not very familiar with our history integration, but this looks good.

@MartinHjelmare
Copy link
Member

Marking it as breaking change so we mention it in release notes for any custom integrations that might use this.

@MartinHjelmare MartinHjelmare merged commit ebed1de into home-assistant:dev May 19, 2020
@bdraco bdraco mentioned this pull request May 20, 2020
20 tasks
@lock lock bot locked and limited conversation to collaborators May 20, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants