diff options
author | Jenkins <jenkins@review.openstack.org> | 2017-02-18 00:40:52 +0000 |
---|---|---|
committer | Gerrit Code Review <review@openstack.org> | 2017-02-18 00:40:52 +0000 |
commit | 3e4dbb5d164543558441b6ba58b4be785144c741 (patch) | |
tree | 3fbb62478c6de367710984328158e9fdaa31e8f9 /neutron/notifiers | |
parent | e6fd02d9415655e3de0fbfb7ad8787ec82a8a0a1 (diff) | |
parent | 255e8a839db0be10c98b5d9f480ce476e2f2e171 (diff) | |
download | neutron-3e4dbb5d164543558441b6ba58b4be785144c741.tar.gz |
Merge "Turn nova notifier into a proper rate limiter"
Diffstat (limited to 'neutron/notifiers')
-rw-r--r-- | neutron/notifiers/batch_notifier.py | 31 |
1 files changed, 15 insertions, 16 deletions
diff --git a/neutron/notifiers/batch_notifier.py b/neutron/notifiers/batch_notifier.py index 0396042dd7..2169796e18 100644 --- a/neutron/notifiers/batch_notifier.py +++ b/neutron/notifiers/batch_notifier.py @@ -11,14 +11,17 @@ # under the License. import eventlet +from oslo_utils import uuidutils + +from neutron.common import utils class BatchNotifier(object): def __init__(self, batch_interval, callback): self.pending_events = [] - self._waiting_to_send = False self.callback = callback self.batch_interval = batch_interval + self._lock_identifier = 'notifier-%s' % uuidutils.generate_uuid() def queue_event(self, event): """Called to queue sending an event with the next batch of events. @@ -30,13 +33,12 @@ class BatchNotifier(object): problematic. This replaces the loopingcall with a mechanism that creates a - short-lived thread on demand when the first event is queued. That - thread will sleep once for the same batch_duration to allow other - events to queue up in pending_events and then will send them when it - wakes. + short-lived thread on demand whenever an event is queued. That thread + will wait for a lock, send all queued events and then sleep for + 'batch_interval' seconds to allow other events to queue up. - If a thread is already alive and waiting, this call will simply queue - the event and return leaving it up to the thread to send it. + This effectively acts as a rate limiter to only allow 1 batch per + 'batch_interval' seconds. :param event: the event that occurred. """ @@ -45,17 +47,14 @@ class BatchNotifier(object): self.pending_events.append(event) - if self._waiting_to_send: - return - - self._waiting_to_send = True - - def last_out_sends(): - eventlet.sleep(self.batch_interval) - self._waiting_to_send = False + @utils.synchronized(self._lock_identifier) + def synced_send(): self._notify() + # sleeping after send while holding the lock allows subsequent + # events to batch up + eventlet.sleep(self.batch_interval) - eventlet.spawn_n(last_out_sends) + eventlet.spawn_n(synced_send) def _notify(self): if not self.pending_events: |