diff options
author | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2014-03-31 19:17:43 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2014-04-01 17:28:53 +0900 |
commit | e1e89ce57f95110d415d1fa368a73ed5eb213a63 (patch) | |
tree | f2215caba3b2f33b4dd689579964ea6c31ea9991 /ryu/services/protocols/bgp/utils/evtlet.py | |
parent | d6bbd8349760e1fb93e74353f751eee1b025912b (diff) |
add BGP daemon feature
Currently, the BGP code can work as an daemon (IOW, not RyuApp).
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Diffstat (limited to 'ryu/services/protocols/bgp/utils/evtlet.py')
-rw-r--r-- | ryu/services/protocols/bgp/utils/evtlet.py | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/ryu/services/protocols/bgp/utils/evtlet.py b/ryu/services/protocols/bgp/utils/evtlet.py new file mode 100644 index 00000000..4dc8a943 --- /dev/null +++ b/ryu/services/protocols/bgp/utils/evtlet.py @@ -0,0 +1,140 @@ +# Copyright (C) 2014 Nippon Telegraph and Telephone Corporation. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +""" + Concurrent networking library - Eventlet, based utilities classes. +""" +import eventlet +from eventlet import event +import logging + +LOG = logging.getLogger('utils.evtlet') + + +class EventletIOFactory(object): + + @staticmethod + def create_custom_event(): + LOG.debug('Create CustomEvent called') + return CustomEvent() + + @staticmethod + def create_looping_call(funct, *args, **kwargs): + LOG.debug('create_looping_call called') + return LoopingCall(funct, *args, **kwargs) + + +class CustomEvent(object): + """Encapsulates eventlet event to provide a event which can recur. + + It has the same interface as threading.Event but works for eventlet. + """ + def __init__(self,): + self._event = event.Event() + self._is_set = False + + def is_set(self): + """Return true if and only if the internal flag is true.""" + return self._is_set + + def set(self): + """Set the internal flag to true. + + All threads waiting for it to become true are awakened. + Threads that call wait() once the flag is true will not block at all. + """ + if self._event and not self._event.ready(): + self._event.send() + self._is_set = True + + def clear(self): + """Reset the internal flag to false. + + Subsequently, threads calling wait() will block until set() is called + to set the internal flag to true again. + """ + if self._is_set: + self._is_set = False + self._event = event.Event() + + def wait(self): + """Block until the internal flag is true. + + If the internal flag is true on entry, return immediately. Otherwise, + block until another thread calls set() to set the flag to true, or + until the optional timeout occurs. + """ + if not self._is_set: + self._event.wait() + + +class LoopingCall(object): + """Call a function repeatedly. + """ + def __init__(self, funct, *args, **kwargs): + self._funct = funct + self._args = args + self._kwargs = kwargs + self._running = False + self._interval = 0 + self._self_thread = None + + @property + def running(self): + return self._running + + @property + def interval(self): + return self._interval + + def __call__(self): + if self._running: + # Schedule next iteration of the call. + self._self_thread = eventlet.spawn_after(self._interval, self) + self._funct(*self._args, **self._kwargs) + + def start(self, interval, now=True): + """Start running pre-set function every interval seconds. + """ + if interval < 0: + raise ValueError('interval must be >= 0') + + if self._running: + self.stop() + + self._running = True + self._interval = interval + if now: + self._self_thread = eventlet.spawn_after(0, self) + else: + self._self_thread = eventlet.spawn_after(self._interval, self) + + def stop(self): + """Stop running scheduled function. + """ + self._running = False + if self._self_thread is not None: + self._self_thread.cancel() + self._self_thread = None + + def reset(self): + """Skip the next iteration and reset timer. + """ + if self._self_thread is not None: + # Cancel currently scheduled call + self._self_thread.cancel() + self._self_thread = None + # Schedule a new call + self._self_thread = eventlet.spawn_after(self._interval, self) |