Browse Source

Load drivers only once in the v2 API

This adds two functions to the BaseResource class of the v2 API: "load"
and "reload". Since flask_restful resources are instantiated on each request,
this allows to load drivers only once.

Story: 2006654
Task 36900

Change-Id: I8fcc3115aae5c33a815980f6946da224000d541a
changes/93/686393/5
Luka Peschke 2 months ago
parent
commit
daafaade8f
4 changed files with 61 additions and 5 deletions
  1. +16
    -1
      cloudkitty/api/v2/base.py
  2. +6
    -4
      cloudkitty/api/v2/scope/state.py
  3. +6
    -0
      cloudkitty/tests/gabbi/fixtures.py
  4. +33
    -0
      doc/source/developer/api/tutorial.rst

+ 16
- 1
cloudkitty/api/v2/base.py View File

@@ -33,6 +33,21 @@ class BaseResource(flask_restful.Resource):
raise http_exceptions.Forbidden(
"You are not authorized to perform this action")

@classmethod
def reload(cls):
"""Reloads all required drivers"""
cls._storage = storage.get_storage()

@classmethod
def load(cls):
"""Loads all required drivers.

If the drivers are already loaded, does nothing.
"""
if not getattr(cls, '_loaded', False):
cls.reload()
cls._loaded = True

def __init__(self, *args, **kwargs):
super(BaseResource, self).__init__(*args, **kwargs)
self._storage = storage.get_storage()
self.load()

+ 6
- 4
cloudkitty/api/v2/scope/state.py View File

@@ -26,10 +26,12 @@ from cloudkitty import validation_utils as vutils


class ScopeState(base.BaseResource):
def __init__(self, *args, **kwargs):
super(ScopeState, self).__init__(*args, **kwargs)
self._client = messaging.get_client()
self._storage_state = storage_state.StateManager()

@classmethod
def reload(cls):
super(ScopeState, cls).reload()
cls._client = messaging.get_client()
cls._storage_state = storage_state.StateManager()

@api_utils.paginated
@api_utils.add_input_schema('query', {

+ 6
- 0
cloudkitty/tests/gabbi/fixtures.py View File

@@ -37,6 +37,8 @@ import wsmeext.pecan as wsme_pecan

from cloudkitty.api import app
from cloudkitty.api import middleware
from cloudkitty.api.v2.dataframes import dataframes as v2_api_dataframes
from cloudkitty.api.v2.summary import summary as v2_api_summary
from cloudkitty import dataframe
from cloudkitty import db
from cloudkitty.db import api as ck_db_api
@@ -459,6 +461,8 @@ class NowInfluxStorageDataFixture(NowStorageDataFixture):
new=lambda **kw: st,
)
self._get_storage_patch.start()
v2_api_summary.Summary.reload()
v2_api_dataframes.DataFrameList.reload()

super(NowInfluxStorageDataFixture, self).start_fixture()

@@ -485,6 +489,8 @@ class InfluxStorageDataFixture(StorageDataFixture):
new=lambda **kw: st,
)
self._get_storage_patch.start()
v2_api_summary.Summary.reload()
v2_api_dataframes.DataFrameList.reload()

super(InfluxStorageDataFixture, self).start_fixture()


+ 33
- 0
doc/source/developer/api/tutorial.rst View File

@@ -234,6 +234,39 @@ However, they can be overriden in ``policy.yaml``. Call them the following way:
# [...]


Loading drivers
---------------

Most of the time, resources need to load some drivers (storage, SQL...).
As the instantiation of these drivers can take some time, this should be done
only once.

Some drivers (like the storage driver) are loaded in ``BaseResource`` and are
thus available to all resources.

Resources requiring some additional drivers should implement the ``reload``
function:

.. code-block:: python

class BaseResource(flask_restful.Resource):

@classmethod
def reload(cls):
"""Reloads all required drivers"""


Here's an example taken from ``cloudkitty.api.v2.scope.state.ScopeState``:

.. code-block:: python

@classmethod
def reload(cls):
super(ScopeState, cls).reload()
cls._client = messaging.get_client()
cls._storage_state = storage_state.StateManager()


Registering resources
=====================


Loading…
Cancel
Save