Sys::Virt::Event integration w/ AnyEvent

Scott Wiersdorf scott at betterservers.com
Sat Mar 15 00:40:24 CET 2014


This is a follow up to a similar question posted back in November about Sys::Virt.

libvirt can provide events about container (VM) events (start/stop/reboot, etc.). The Perl XS wrapper for libvirt is Sys::Virt. Sys::Virt also provides an event loop contract via Sys::Virt::Event, but I’m having a nearly impossible time understanding how to make it work with AnyEvent.

I’ve looked carefully at all of the included AnyEvent::Impl::* libraries, per the "SUPPLYING YOUR OWN EVENT MODEL INTERFACE" documentation in AnyEvent.pm and just don’t see how the two overlap. Sys::Virt::Event supplies a run_default() method that runs a single iteration of its loop. I’ve been able to hack something like this:

while (! $quit) {
    EV::run EV::RUN_ONCE;  ## find my events
    $ev->run_default();    ## find libvirt events
}

where $ev is an instance of Sys::Virt::Event, but this feels terrible and wrong to me. Here is an example of using Sys::Virt’s events by itself (from Sys::Virt’s examples directory):

#!/usr/bin/env perl
use strict;
use warnings;
use feature 'say';
use feature 'current_sub';

use Sys::Virt;
use Sys::Virt::Domain;
use Sys::Virt::Event;

Sys::Virt::Event::register_default();

my $quit = 0;

## sysvirt connection
my $conn = Sys::Virt->new(uri => "remote:///system", readonly => 1);

$conn->domain_event_register_any(undef,
                                 Sys::Virt::Domain::EVENT_ID_LIFECYCLE,    ## listen for start/stop/reboot events
                                 sub { my ($sv, $dom, $evt, $detail) = @_; ## this is the callback
                                       say STDERR $dom->get_name });

$conn->register_close_callback( sub { $quit = 1 } );

## poor man’s event loop
while (! $quit) {
    Sys::Virt::Event::run_default;
}

Under the hood, libvirt connects to a unix domain socket, speaks the right protocol to subscribe to the EVENT_ID_LIFECYCLE event, then registers my callback which fires when the event occurs (I think it uses epoll on the fd). I’d prefer to let EV run the loop (via EV::run), rather than run two loops so I can catch all my events.

Other things we’ve tried is putting this run_default into an AnyEvent->timer watcher, which works ok, but gives lower resolution than we’d like… 

Has anyone successfully integrated Sys::Virt::Event with AnyEvent (or EV—I’m not even sure how to ask this correctly)?

Scott

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.schmorp.de/pipermail/anyevent/attachments/20140314/48353d6a/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 496 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: <http://lists.schmorp.de/pipermail/anyevent/attachments/20140314/48353d6a/attachment.sig>


More information about the anyevent mailing list