vici: Provide a way to stop listening and re-connect in Python bindings
This allows re-connecting to a new session in a disconnect listener and continue listening without having to return from listen(). The exception can also be used to stop listening after some condition (e.g. to wait until a specific SA got created and then stop).
This commit is contained in:
@@ -1,2 +1,2 @@
|
|||||||
from .event_listener import EventListener
|
from .event_listener import EventListener, StopListening
|
||||||
from .session import Session
|
from .session import Session
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
from functools import wraps
|
from functools import wraps
|
||||||
|
|
||||||
|
|
||||||
|
class StopListening(Exception):
|
||||||
|
"""Exception that may be raised to stop listening for events."""
|
||||||
|
|
||||||
|
|
||||||
class EventListener(object):
|
class EventListener(object):
|
||||||
def __init__(self, session=None):
|
def __init__(self, session=None):
|
||||||
"""Create an event listener instance, which provides decorator methods
|
"""Create an event listener instance, which provides decorator methods
|
||||||
@@ -30,7 +34,8 @@ class EventListener(object):
|
|||||||
"""Decorator to mark a function as a listener for specific events.
|
"""Decorator to mark a function as a listener for specific events.
|
||||||
|
|
||||||
The decorated function is expected to receive the name of the event and
|
The decorated function is expected to receive the name of the event and
|
||||||
the data as arguments.
|
the data as arguments. It may raise :class:`~StopListening` to stop
|
||||||
|
listening and let :func:`~listen()` return.
|
||||||
|
|
||||||
:param events: events to register and call decorated function for
|
:param events: events to register and call decorated function for
|
||||||
:type events: list
|
:type events: list
|
||||||
@@ -48,8 +53,12 @@ class EventListener(object):
|
|||||||
|
|
||||||
def on_disconnected(self):
|
def on_disconnected(self):
|
||||||
"""Decorator to mark a function as a listener for when the daemon
|
"""Decorator to mark a function as a listener for when the daemon
|
||||||
disconnects the vici session. This listener instance is passed to the
|
disconnects the vici session.
|
||||||
decorated function.
|
|
||||||
|
This listener instance is passed to the decorated function, which may
|
||||||
|
be used to set a new session and continue listening. If no session is
|
||||||
|
set, :func:`~listen()` will return after the decorated function has
|
||||||
|
been called.
|
||||||
|
|
||||||
:return: decorator function
|
:return: decorator function
|
||||||
:rtype: any
|
:rtype: any
|
||||||
@@ -66,20 +75,27 @@ class EventListener(object):
|
|||||||
def listen(self):
|
def listen(self):
|
||||||
"""Dispatch events registered via decorators of this instance.
|
"""Dispatch events registered via decorators of this instance.
|
||||||
|
|
||||||
This method does not return unless the daemon disconnects or an
|
|
||||||
exception occurs.
|
|
||||||
|
|
||||||
An active session has to be set before calling this. After getting
|
An active session has to be set before calling this. After getting
|
||||||
disconnected, a new session may be set via :func:`~set_session()`
|
disconnected, a new session may be set via :func:`~set_session()` in
|
||||||
before calling this again.
|
a function decorated with :func:`~on_disconnected()` to resume
|
||||||
|
listening for events.
|
||||||
|
|
||||||
|
This method does not return unless :class:`~StopListening` or an
|
||||||
|
unexpected exception is raised or if the current session is disconnected
|
||||||
|
and no new session is set in a listener.
|
||||||
"""
|
"""
|
||||||
try:
|
while True:
|
||||||
if self.session is None:
|
try:
|
||||||
return
|
if self.session is None:
|
||||||
for label, event in self.session.listen(self.event_map.keys()):
|
break
|
||||||
name = label.decode()
|
for label, event in self.session.listen(self.event_map.keys()):
|
||||||
if name in self.event_map:
|
name = label.decode()
|
||||||
self.event_map[name](name, event)
|
if name in self.event_map:
|
||||||
except IOError:
|
self.event_map[name](name, event)
|
||||||
for func in self.disconnect_list:
|
except IOError:
|
||||||
func(self)
|
self.session = None
|
||||||
|
for func in self.disconnect_list:
|
||||||
|
func(self)
|
||||||
|
continue
|
||||||
|
except StopListening:
|
||||||
|
break
|
||||||
|
|||||||
Reference in New Issue
Block a user