hooklift / node-libvirt

libvirt bindings for google v8 javascript engine (nodejs addon)
http://c4milo.github.io/node-libvirt/
178 stars 52 forks source link

Events not firing #75

Open Hibryda opened 8 years ago

Hibryda commented 8 years ago

I have a piece of code:

vapp.hyperv = new virt.Hypervisor(vapp.hyperv_string)
  vapp.hyperv.connectAsync()
    .then(() =>
      vapp.domain = vapp.hyperv.lookupDomainByNameAsync(name)
    )
    .then((domain) => {
      vapp.domain = domain
      vapp.ev_lifecycle = domain.registerEvent(
        {evtype:virt.VIR_DOMAIN_EVENT_ID_LIFECYCLE},
        function (hyp, dom, data) {
            console.log(hyp, dom, data)
      })
    return vapp.domain.getInfoAsync()
    })
...

After running the above I get the following error: libvirt: error : internal error: could not initialize domain event timer

Why is it so?

atoy40 commented 8 years ago

Hello,

you've to call virt.startEventLoop() first to register libvirt event manager with the nodejs event loop.

Anthony.

Hibryda commented 8 years ago

Thanks. Will try.

Hibryda commented 8 years ago

Ok, tried with calling virt.startEventLoop() . It actually works somehow, as it now reacts to events. But not the one that is attached. Just for quick try I attached reboot event and rebooted the vm form virt-manager. The output from console of my app shows GENERIC CALLBACK CALLEDGENERIC CALLBACK CALLED. But not the callback I attached. More, the callback gets executed immediately when registration performs. I've checked in the source and arguments for event registration should be [object, function]. So doing properly. No idea what am I doing wrong now.

Hibryda commented 8 years ago

Dug a little further and see that generic is attached to reboot. More, generic emits no event, just prints the above. The above changes actually nothing as I still have no clue how to register event without calling callback immediately.

atoy40 commented 8 years ago

@Hibryda

First, use registerEventAsync (the promised version of the function) instead of registerEvent. Then, the libvirt domain acts as a EventEmitter, so you can use something looking like :

.then((domain) => {
    vapp.domain = domain;
    return domain.registerEventAsync({ evtype: virt.VIR_DOMAIN_EVENT_ID_LIFECYCLE })
})
.then((callbackId) => {
    vapp.domain.on('lifecycleEvent', (data) => {
        console.log("lifecycleEvent fired : "+JSON.stringify(data));
    });
    return vapp.domain.getInfoAsync();
})
.then((info)  => {
    ....
}

You can use callbackId to unregister the event handling :

domain.unregisterEventAsync(callbackId).then(.....);

Anthony.

Hibryda commented 8 years ago

I just thought that there is a way to register an event and attach function in one step (like addEventListener). Apparently must do it in two steps. Thanks for the answer.