Make a proper driver notification API

We sometimes have need to send notifications to certain driver objects.
A "notification" is a call to an object to indicate some condition has
changed, and the callee may choose to act on that, or totally ignore it.
Currently, the only notification is NodeRequestHandler.nodeReused() but
this adds another notification for the Provider objects in preparation
for static node driver changes.

Since it is entirely probable we may want more in the future, this
change organizes the notifications into proper classes for easy
identification/manipulation. It will be a naming standard end these
notification method names with "Notification".

Change-Id: I905ef42bb434435cbe3cec0f5007981a5b789769
This commit is contained in:
David Shrewsbury 2018-06-12 17:09:51 -04:00
parent a418aabb7a
commit 326de1eedb
4 changed files with 45 additions and 11 deletions

View File

@ -58,7 +58,11 @@ Drivers
:members:
.. autoclass:: nodepool.driver.Provider
:members:
.. autoclass:: nodepool.driver.ProviderNotifications
:members:
.. autoclass:: nodepool.driver.NodeRequestHandler
:members:
.. autoclass:: nodepool.driver.NodeRequestHandlerNotifications
:members:
.. autoclass:: nodepool.driver.ProviderConfig
:members:

View File

@ -131,7 +131,25 @@ class Driver(object, metaclass=abc.ABCMeta):
pass
class Provider(object, metaclass=abc.ABCMeta):
class ProviderNotifications(object):
"""
Notification interface for :class:`.Provider` objects.
This groups all notification messages bound for the Provider. The
Provider class inherits from this by default. A Provider overrides the
methods here if they want to handle the notification.
"""
def nodeDeletedNotification(self, node):
"""
Called after the ZooKeeper object for a node is deleted.
:param Node node: Object describing the node just deleted.
"""
pass
class Provider(ProviderNotifications, metaclass=abc.ABCMeta):
"""The Provider interface
Drivers implement this interface to supply Providers. Each
@ -283,7 +301,25 @@ class LabelRecorder(object):
return node_id
class NodeRequestHandler(object, metaclass=abc.ABCMeta):
class NodeRequestHandlerNotifications(object):
"""
Notification interface for :class:`.NodeRequestHandler` objects.
This groups all notification messages bound for the NodeRequestHandler.
The NodeRequestHandler class inherits from this by default. A request
handler overrides the methods here if they want to handle the notification.
"""
def nodeReusedNotification(self, node):
'''
Handler may implement this to be notified when a node is re-used.
The OpenStack handler uses this to set the choozen_az.
'''
pass
class NodeRequestHandler(NodeRequestHandlerNotifications,
metaclass=abc.ABCMeta):
'''
Class to process a single nodeset request.
@ -402,7 +438,7 @@ class NodeRequestHandler(object, metaclass=abc.ABCMeta):
self.nodeset.append(node)
self._satisfied_types.add(ntype, node.id)
# Notify driver handler about node re-use
self.nodeReused(node)
self.nodeReusedNotification(node)
break
# Could not grab an existing node, so launch a new one.
@ -672,13 +708,6 @@ class NodeRequestHandler(object, metaclass=abc.ABCMeta):
'''
return True
def nodeReused(self, node):
'''
Handler may implement this to be notified when a node is re-used.
The OpenStack handler uses this to set the choozen_az.
'''
pass
def checkReusableNode(self, node):
'''
Handler may implement this to verify a node can be re-used.

View File

@ -341,7 +341,7 @@ class OpenStackNodeRequestHandler(NodeRequestHandler):
return False
return True
def nodeReused(self, node):
def nodeReusedNotification(self, node):
"""
We attempt to group the node set within the same provider availability
zone.

View File

@ -97,6 +97,7 @@ class NodeDeleter(threading.Thread, stats.StatsReporter):
node.id, node.state, node.external_id)
# This also effectively releases the lock
zk_conn.deleteNode(node)
manager.nodeDeletedNotification(node)
def run(self):
# Since leaked instances won't have an actual node in ZooKeeper,