Reuse 'periodic_task' from oslo_service
Remove Manila code related to 'periodic_tasks' and reuse it from 'oslo_service' library. Also, add call of parent's '__init__' method for 'manila.db.base.Base' class. It is required for proper work of multiple inheritance where this class is inherited. And remove it from inheritance by 'manila.network.neutron.api.API' class as redundant. Change-Id: I138fc2f475f8858788a9ab00f84ab9ee167a95c5
This commit is contained in:
parent
8d0c93d3d7
commit
48221b0f4c
@ -31,6 +31,7 @@ class Base(object):
|
|||||||
"""DB driver is injected in the init method."""
|
"""DB driver is injected in the init method."""
|
||||||
|
|
||||||
def __init__(self, db_driver=None):
|
def __init__(self, db_driver=None):
|
||||||
|
super(Base, self).__init__()
|
||||||
if not db_driver:
|
if not db_driver:
|
||||||
db_driver = CONF.db_driver
|
db_driver = CONF.db_driver
|
||||||
self.db = importutils.import_module(db_driver) # pylint: disable=C0103
|
self.db = importutils.import_module(db_driver) # pylint: disable=C0103
|
||||||
|
@ -53,10 +53,9 @@ This module provides Manager, a base class for managers.
|
|||||||
|
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
from oslo_log import log
|
from oslo_log import log
|
||||||
import six
|
from oslo_service import periodic_task
|
||||||
|
|
||||||
from manila.db import base
|
from manila.db import base
|
||||||
from manila.i18n import _LE
|
|
||||||
from manila.scheduler import rpcapi as scheduler_rpcapi
|
from manila.scheduler import rpcapi as scheduler_rpcapi
|
||||||
from manila import version
|
from manila import version
|
||||||
|
|
||||||
@ -64,69 +63,12 @@ CONF = cfg.CONF
|
|||||||
LOG = log.getLogger(__name__)
|
LOG = log.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def periodic_task(*args, **kwargs):
|
class PeriodicTasks(periodic_task.PeriodicTasks):
|
||||||
"""Decorator to indicate that a method is a periodic task.
|
def __init__(self):
|
||||||
|
super(PeriodicTasks, self).__init__(CONF)
|
||||||
This decorator can be used in two ways:
|
|
||||||
|
|
||||||
1. Without arguments '@periodic_task', this will be run on every tick
|
|
||||||
of the periodic scheduler.
|
|
||||||
|
|
||||||
2. With arguments, @periodic_task(ticks_between_runs=N), this will be
|
|
||||||
run on every N ticks of the periodic scheduler.
|
|
||||||
"""
|
|
||||||
def decorator(f):
|
|
||||||
f._periodic_task = True
|
|
||||||
f._ticks_between_runs = kwargs.pop('ticks_between_runs', 0)
|
|
||||||
return f
|
|
||||||
|
|
||||||
# NOTE(sirp): The `if` is necessary to allow the decorator to be used with
|
|
||||||
# and without parens.
|
|
||||||
#
|
|
||||||
# In the 'with-parens' case (with kwargs present), this function needs to
|
|
||||||
# return a decorator function since the interpreter will invoke it like:
|
|
||||||
#
|
|
||||||
# periodic_task(*args, **kwargs)(f)
|
|
||||||
#
|
|
||||||
# In the 'without-parens' case, the original function will be passed
|
|
||||||
# in as the first argument, like:
|
|
||||||
#
|
|
||||||
# periodic_task(f)
|
|
||||||
if kwargs:
|
|
||||||
return decorator
|
|
||||||
else:
|
|
||||||
return decorator(args[0])
|
|
||||||
|
|
||||||
|
|
||||||
class ManagerMeta(type):
|
class Manager(base.Base, PeriodicTasks):
|
||||||
def __init__(cls, names, bases, dict_):
|
|
||||||
"""Metaclass that allows us to collect decorated periodic tasks."""
|
|
||||||
super(ManagerMeta, cls).__init__(names, bases, dict_)
|
|
||||||
|
|
||||||
# NOTE(sirp): if the attribute is not present then we must be the base
|
|
||||||
# class, so, go ahead an initialize it. If the attribute is present,
|
|
||||||
# then we're a subclass so make a copy of it so we don't step on our
|
|
||||||
# parent's toes.
|
|
||||||
try:
|
|
||||||
cls._periodic_tasks = cls._periodic_tasks[:]
|
|
||||||
except AttributeError:
|
|
||||||
cls._periodic_tasks = []
|
|
||||||
|
|
||||||
try:
|
|
||||||
cls._ticks_to_skip = cls._ticks_to_skip.copy()
|
|
||||||
except AttributeError:
|
|
||||||
cls._ticks_to_skip = {}
|
|
||||||
|
|
||||||
for value in cls.__dict__.values():
|
|
||||||
if getattr(value, '_periodic_task', False):
|
|
||||||
task = value
|
|
||||||
name = task.__name__
|
|
||||||
cls._periodic_tasks.append((name, task))
|
|
||||||
cls._ticks_to_skip[name] = task._ticks_between_runs
|
|
||||||
|
|
||||||
|
|
||||||
@six.add_metaclass(ManagerMeta)
|
|
||||||
class Manager(base.Base):
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def RPC_API_VERSION(self):
|
def RPC_API_VERSION(self):
|
||||||
@ -153,29 +95,7 @@ class Manager(base.Base):
|
|||||||
|
|
||||||
def periodic_tasks(self, context, raise_on_error=False):
|
def periodic_tasks(self, context, raise_on_error=False):
|
||||||
"""Tasks to be run at a periodic interval."""
|
"""Tasks to be run at a periodic interval."""
|
||||||
for task_name, task in self._periodic_tasks:
|
return self.run_periodic_tasks(context, raise_on_error=raise_on_error)
|
||||||
full_task_name = '.'.join([self.__class__.__name__, task_name])
|
|
||||||
|
|
||||||
ticks_to_skip = self._ticks_to_skip[task_name]
|
|
||||||
if ticks_to_skip > 0:
|
|
||||||
LOG.debug("Skipping %(full_task_name)s, %(ticks_to_skip)s"
|
|
||||||
" ticks left until next run",
|
|
||||||
{'full_task_name': full_task_name,
|
|
||||||
'ticks_to_skip': ticks_to_skip})
|
|
||||||
self._ticks_to_skip[task_name] -= 1
|
|
||||||
continue
|
|
||||||
|
|
||||||
self._ticks_to_skip[task_name] = task._ticks_between_runs
|
|
||||||
LOG.debug("Running periodic task %(full_task_name)s",
|
|
||||||
{'full_task_name': full_task_name})
|
|
||||||
|
|
||||||
try:
|
|
||||||
task(self, context)
|
|
||||||
except Exception as e:
|
|
||||||
if raise_on_error:
|
|
||||||
raise
|
|
||||||
LOG.exception(_LE("Error during %(full_task_name)s: %(e)s"),
|
|
||||||
{'full_task_name': full_task_name, 'e': e})
|
|
||||||
|
|
||||||
def init_host(self):
|
def init_host(self):
|
||||||
"""Handle initialization if this is a standalone service.
|
"""Handle initialization if this is a standalone service.
|
||||||
@ -215,7 +135,7 @@ class SchedulerDependentManager(Manager):
|
|||||||
"""Remember these capabilities to send on next periodic update."""
|
"""Remember these capabilities to send on next periodic update."""
|
||||||
self.last_capabilities = capabilities
|
self.last_capabilities = capabilities
|
||||||
|
|
||||||
@periodic_task
|
@periodic_task.periodic_task
|
||||||
def _publish_service_capabilities(self, context):
|
def _publish_service_capabilities(self, context):
|
||||||
"""Pass data back to the scheduler at a periodic interval."""
|
"""Pass data back to the scheduler at a periodic interval."""
|
||||||
if self.last_capabilities:
|
if self.last_capabilities:
|
||||||
|
@ -20,7 +20,6 @@ from oslo_config import cfg
|
|||||||
from oslo_log import log
|
from oslo_log import log
|
||||||
|
|
||||||
from manila import context
|
from manila import context
|
||||||
from manila.db import base
|
|
||||||
from manila import exception
|
from manila import exception
|
||||||
from manila.i18n import _LE
|
from manila.i18n import _LE
|
||||||
from manila.network.neutron import constants as neutron_constants
|
from manila.network.neutron import constants as neutron_constants
|
||||||
@ -78,14 +77,13 @@ CONF = cfg.CONF
|
|||||||
LOG = log.getLogger(__name__)
|
LOG = log.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class API(base.Base):
|
class API(object):
|
||||||
"""API for interacting with the neutron 2.x API.
|
"""API for interacting with the neutron 2.x API.
|
||||||
|
|
||||||
:param configuration: instance of config or config group.
|
:param configuration: instance of config or config group.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, config_group_name=None):
|
def __init__(self, config_group_name=None):
|
||||||
super(API, self).__init__()
|
|
||||||
self.config_group_name = config_group_name or 'DEFAULT'
|
self.config_group_name = config_group_name or 'DEFAULT'
|
||||||
CONF.register_opts(neutron_opts, group=self.config_group_name)
|
CONF.register_opts(neutron_opts, group=self.config_group_name)
|
||||||
self.configuration = getattr(CONF, self.config_group_name, CONF)
|
self.configuration = getattr(CONF, self.config_group_name, CONF)
|
||||||
|
@ -24,6 +24,7 @@ import datetime
|
|||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
from oslo_log import log
|
from oslo_log import log
|
||||||
from oslo_serialization import jsonutils
|
from oslo_serialization import jsonutils
|
||||||
|
from oslo_service import periodic_task
|
||||||
from oslo_utils import excutils
|
from oslo_utils import excutils
|
||||||
from oslo_utils import importutils
|
from oslo_utils import importutils
|
||||||
from oslo_utils import timeutils
|
from oslo_utils import timeutils
|
||||||
@ -578,7 +579,7 @@ class ShareManager(manager.SchedulerDependentManager):
|
|||||||
"deletion of last share.", share_server['id'])
|
"deletion of last share.", share_server['id'])
|
||||||
self.delete_share_server(context, share_server)
|
self.delete_share_server(context, share_server)
|
||||||
|
|
||||||
@manager.periodic_task(ticks_between_runs=600 / CONF.periodic_interval)
|
@periodic_task.periodic_task(spacing=600)
|
||||||
def delete_free_share_servers(self, ctxt):
|
def delete_free_share_servers(self, ctxt):
|
||||||
if not (self.driver.driver_handles_share_servers and
|
if not (self.driver.driver_handles_share_servers and
|
||||||
self.configuration.automatic_share_server_cleanup):
|
self.configuration.automatic_share_server_cleanup):
|
||||||
@ -702,7 +703,7 @@ class ShareManager(manager.SchedulerDependentManager):
|
|||||||
context, access_id, {'state': access_ref.STATE_ERROR})
|
context, access_id, {'state': access_ref.STATE_ERROR})
|
||||||
self.db.share_access_delete(context, access_id)
|
self.db.share_access_delete(context, access_id)
|
||||||
|
|
||||||
@manager.periodic_task
|
@periodic_task.periodic_task(spacing=CONF.periodic_interval)
|
||||||
def _report_driver_status(self, context):
|
def _report_driver_status(self, context):
|
||||||
LOG.info(_LI('Updating share status'))
|
LOG.info(_LI('Updating share status'))
|
||||||
share_stats = self.driver.get_share_stats(refresh=True)
|
share_stats = self.driver.get_share_stats(refresh=True)
|
||||||
|
@ -30,7 +30,6 @@ class ManagerTestCase(test.TestCase):
|
|||||||
db_driver = 'fake_driver'
|
db_driver = 'fake_driver'
|
||||||
fake_manager = manager.Manager(host, db_driver)
|
fake_manager = manager.Manager(host, db_driver)
|
||||||
self.assertTrue(hasattr(fake_manager, '_periodic_tasks'))
|
self.assertTrue(hasattr(fake_manager, '_periodic_tasks'))
|
||||||
self.assertTrue(hasattr(fake_manager, '_ticks_to_skip'))
|
|
||||||
self.assertTrue(hasattr(fake_manager, 'additional_endpoints'))
|
self.assertTrue(hasattr(fake_manager, 'additional_endpoints'))
|
||||||
self.assertTrue(hasattr(fake_manager, 'host'))
|
self.assertTrue(hasattr(fake_manager, 'host'))
|
||||||
self.assertTrue(hasattr(fake_manager, 'periodic_tasks'))
|
self.assertTrue(hasattr(fake_manager, 'periodic_tasks'))
|
||||||
@ -51,7 +50,6 @@ class SchedulerDependentManagerTestCase(test.TestCase):
|
|||||||
fake_sched_manager = manager.SchedulerDependentManager(
|
fake_sched_manager = manager.SchedulerDependentManager(
|
||||||
host, db_driver, service_name)
|
host, db_driver, service_name)
|
||||||
self.assertTrue(hasattr(fake_sched_manager, '_periodic_tasks'))
|
self.assertTrue(hasattr(fake_sched_manager, '_periodic_tasks'))
|
||||||
self.assertTrue(hasattr(fake_sched_manager, '_ticks_to_skip'))
|
|
||||||
self.assertTrue(hasattr(fake_sched_manager, 'additional_endpoints'))
|
self.assertTrue(hasattr(fake_sched_manager, 'additional_endpoints'))
|
||||||
self.assertTrue(hasattr(fake_sched_manager, 'host'))
|
self.assertTrue(hasattr(fake_sched_manager, 'host'))
|
||||||
self.assertTrue(hasattr(fake_sched_manager, 'periodic_tasks'))
|
self.assertTrue(hasattr(fake_sched_manager, 'periodic_tasks'))
|
||||||
|
Loading…
Reference in New Issue
Block a user