Watchers

Common methods and attributes

Watcher is the base class for all watchers. Though it is not exposed to users, its methods and attributes are described here.

class Watcher
start()

Starts (activates) the watcher. Only active watchers will receive events. If the watcher is already active nothing will happen.

stop()

Stops the watcher if active, and clears the pending status (whether the watcher was active or not). It is possible that stopped watchers are pending - for example, non-repeating timers are being stopped when they become pending - but stop() ensures that the watcher is neither active nor pending.

invoke(revents)
Parameters:revents (int) – See Events received for valid values.

Invoke the watcher callback with the given revents.

clear()
Return type:int

If the watcher is pending, this method clears its pending status and returns its revents bitset (as if its callback was invoked). If the watcher isn’t pending it does nothing and returns 0. Sometimes it can be useful to “poll” a watcher instead of waiting for its callback to be invoked, which can be accomplished with this method.

feed(revents)
Parameters:revents (int) – See Events received for valid values.

Feeds the given revents set into the event loop, as if the specified event had happened for the watcher.

loop

Read only

Loop object responsible for the watcher.

callback

The current watcher callback, its signature must be:

callback(watcher, revents)
Parameters:

As a rule you should not let a callback return with unhandled exceptions. The loop “does not know” how to correctly handle an exception happening in your callback (it depends largely on what you are doing), so, by default, it will just print a warning and suppress it. If you want to act on an exception, you’re better off doing it in the callback (where you are allowed to do anything needed, like logging, stopping, restarting the loop, etc.). Example:

def mycallback(watcher, revents):
    try:
        pass # do something interesting
    except Exception as err:
        # stop the watcher
        watcher.stop()
        # stop the loop
        watcher.loop.stop()
        # and finally raise err
        raise err

If you have a lot of callbacks, use decorators:

import logging

def mydecorator(func):
    def wrap(watcher, revents):
        try:
            func(watcher, revents)
        except RuntimeError: # these are not fatal
            # this will also log the traceback
            logging.exception("stopping {0}".format(watcher))
            # stop the watcher but let the loop continue on its merry way
            watcher.stop()
        except Exception as err: # all other exceptions are fatal
            # stop the watcher
            watcher.stop()
            # stop the loop
            watcher.loop.stop()
            # and finally raise err
            raise err
    return wrap

@mydecorator
def mycallback(watcher, revents):
    pass #do something interesting

Note

As a convenience mood.event provides a fatal() decorator. If a callback decorated with fatal() raises an exception the loop is stopped and the exception raised.

Contrast:

>>> from signal import SIGINT
>>> from mood.event import Loop, EV_TIMER, EV_SIGNAL
>>>
>>> def mycallback(watcher, revents):
...     if (revents & EV_TIMER):
...         raise Exception("TEST")
...     elif (revents & EV_SIGNAL):
...         watcher.loop.stop()
...
>>>
>>> loop = Loop()
>>> timer = loop.timer(0, 2, mycallback)
>>> timer.start()
>>> sig = loop.signal(SIGINT, mycallback) # will catch KeyboardInterrupt
>>> sig.start()
>>> loop.start()
Exception ignored in: <function mycallback at 0x7f4a4b057f28>
Traceback (most recent call last):
  File "<stdin>", line 3, in mycallback
Exception: TEST
Exception ignored in: <function mycallback at 0x7f4a4b057f28>
Traceback (most recent call last):
  File "<stdin>", line 3, in mycallback
Exception: TEST
Exception ignored in: <function mycallback at 0x7f4a4b057f28>
Traceback (most recent call last):
  File "<stdin>", line 3, in mycallback
Exception: TEST
^CTrue
>>>

and:

>>> from mood.event import Loop, fatal
>>>
>>> @fatal
... def mycallback(watcher, revents):
...     raise Exception("TEST")
...
>>>
>>> loop = Loop()
>>> timer = loop.timer(0, 2, mycallback)
>>> timer.start()
>>> loop.start()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in mycallback
Exception: TEST
>>>
data

watcher data.

priority

Set and query the priority of the watcher. The priority is a small integer between EV_MINPRI and EV_MAXPRI. Pending watchers with higher priority will be invoked before watchers with lower priority, but priority will not keep watchers from being executed. If you need to suppress invocation when higher priority events are pending you need to look at Idle watchers, which provide this functionality.

Setting a priority outside the range of EV_MINPRI to EV_MAXPRI is fine, as long as you do not mind that the priority value you query might or might not have been clamped to the valid range.

The default priority used by watchers when no priority has been set is always 0.

Note

You must not change the priority of a watcher as long as it is active or pending.

active

Read only

True if the watcher is active (i.e. it has been started and not yet been stopped), False otherwise.

Note

As long as a watcher is active you must not modify it.

pending

Read only

True if the watcher is pending (i.e. it has outstanding events but its callback has not yet been invoked), False otherwise.

Events received

EV_IO
EV_READ

The file descriptor in the Io watcher has become readable.

EV_WRITE

The file descriptor in the Io watcher has become writable.

EV_TIMER

The Timer watcher has timed out.

EV_PERIODIC

The Periodic or Scheduler watcher has timed out.

EV_SIGNAL

The signal specified in the Signal watcher has been received by a thread.

EV_CHILD

The pid specified in the Child watcher has received a status change.

EV_IDLE

The Idle watcher has determined that you have nothing better to do.

EV_PREPARE
EV_CHECK

All Prepare watchers are invoked just before the loop starts to gather new events, and all Check watchers are queued (not invoked) just after the loop has gathered them, but before it queues any callbacks for any received events. That means Prepare watchers are the last watchers invoked before the event loop sleeps or polls for new events, and Check watchers will be invoked before any other watchers of the same or lower priority within an event loop iteration. Callbacks of both watcher types can start and stop as many watchers as they want, and all of them will be taken into account (for example, a Prepare watcher might start an Idle watcher to keep the loop from blocking).

EV_EMBED

The embedded event loop specified in the Embed watcher needs attention.

EV_FORK

The event loop has been resumed in the child process after fork (see Fork).

EV_ASYNC

The given Async watcher has been asynchronously notified.

EV_CUSTOM

Not ever sent (or otherwise used) by libev itself, but can be freely used by users to signal watchers (e.g. via feed()).

EV_ERROR

An unspecified error has occurred, the watcher has been stopped. This might happen because the watcher could not be properly started because libev ran out of memory, a file descriptor was found to be closed or any other problem.

Warning

mood.event handle this event as a fatal error. On receiving this event the loop and the watcher will be stopped (the callback will not be invoked). In practice, users should never receive this event (still present for testing puposes).

Priorities

EV_MINPRI

default: -2.

EV_MAXPRI

default: 2.