Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose virEventAddHandle #116

Open
purpleidea opened this issue Oct 18, 2016 · 11 comments
Open

Expose virEventAddHandle #116

purpleidea opened this issue Oct 18, 2016 · 11 comments

Comments

@purpleidea
Copy link
Collaborator

It's very important to get events when things happen in libvirt. I've been digging into this code and the libvirt code (in particular virevent.c), and have some observations:

Calling EventRunDefaultImpl in a loop, is useless without virEventAddTimeout because there is no way to trigger it to return so you can shutdown and break that polling loop if the EventRunDefaultImpl call is blocked. However, for some reason it seems to return in bursts every 5 seconds... Anyone know why?

Secondly, is there a way in libvirt to switch to a select style wait, instead of a polling style loop?

Thanks!

@vincentbernat
Copy link
Collaborator

vincentbernat commented Oct 18, 2016

The default implementation is already "evented". You should use it like this:

        go func() {
            for {
                if res := libvirt.EventRunDefaultImpl(); res < 0 {
                    // Report the error somehow or break the loop.
                }
            }
        }()

EventRunDefaultImpl() will wait for one event and handle it, then return. If you want to interrupt it, you can either wait for some event to happen (if you use keepalives, there are events even nothing happens) or you will need to use a pipe and register one end in the event loop to trigger an event (or like you suggest, register a timeout). Unfortunately, those parts are not currently exposed in libvirt-go. I don't bother stopping it, I start it using sync.Once. You can also start it in init().

@purpleidea
Copy link
Collaborator Author

On Tue, Oct 18, 2016 at 3:06 PM, Vincent Bernat
[email protected] wrote:

EventRunDefaultImpl() will wait for one event and handle it, then return. If you want to interrupt it, you can either wait for some event to happen (if you use keepalives, there are events even nothing happens) or you will need to use a pipe and register one end in the event loop to trigger an event. Unfortunately, those parts are not currently exposed in libvirt-go. I don't bother stopping it, I start it using sync.Once. You can also start it in init().

Any idea why it triggers in bursts every five seconds?

@vincentbernat
Copy link
Collaborator

Do you use keepalives?

@purpleidea
Copy link
Collaborator Author

Do you use keepalives?

Haven't added any yet. Unless they are added automatically when you use something else...

@vincentbernat
Copy link
Collaborator

They are not used automatically. But you don't have any events? Or maybe you are just concerned by the fact that you have bursts? In this case, I wouldn't care much. Maybe an event is translated or trigger several events and EventRunDefaultImpl() only handles them one at a time.

@purpleidea
Copy link
Collaborator Author

@vincentbernat Okay, is there any way to cause EventRunDefaultImpl to return ?

@vincentbernat
Copy link
Collaborator

Not from Go. We need to expose virEventAddHandle(). Then, you can interrupt EventRunDefaultImpl() by using Pipe() and registering the reader part with virEventAddHandle(). Then, when you want to stop EventRunDefaultImpl(), you set some "stop" flag and write to the pipe. Break the for loop when the stop flag is set.

I don't think that's useful as you can run the for loop in a separate go routine and never really need to stop it. The loop handles libvirt internal events and as libvirt is thread safe, there is no downside to running it in a separate goroutine/thread.

@purpleidea
Copy link
Collaborator Author

@vincentbernat Fully agree with everything you said, except that I think it would be more correct to "clean it up" by guaranteeing an exit (besides when golang just exits).

Thanks for confirmation. I'm going to aim to go for the easier patches first, but maybe I'll loop back around to this one. Cheers!

@purpleidea purpleidea reopened this Oct 19, 2016
@purpleidea purpleidea changed the title Events in libvirt Expose virEventAddHandle Oct 19, 2016
@vincentbernat
Copy link
Collaborator

Without exposing virEventAddXXX(), we could have EventRunDefaultImplWithContext() that would take a context and make the whole stuff cancellable. We would still need to do all the pipe dance but not exposing virEventAddHandle() is easier since we don't have to handle callbacks.

@rmohr
Copy link
Collaborator

rmohr commented Nov 25, 2016

@purpleidea in case you want to use the libvirt events for you mgmt project, I collected some of the shortcomings of the libvirt events today and started a discussion on the libvirt mailinglis on how to improve them [1].

[1] https://www.redhat.com/archives/libvir-list/2016-November/msg01318.html

@purpleidea
Copy link
Collaborator Author

@rmohr Awesome, thank you for starting the discussion... Couple of questions:

  1. missed events

Have you been able to cause this to happen? If so, it should be reported as a serious bug. Is it being tracked somewhere, and can you reproduce it?

  1. responsiveness of my VM state watchers

Out of curiosity, what is your application for all this? AFAICT, you're not working on mgmt at the moment...

  1. Want to help out with mgmt? Come hang with us in #mgmtconfig on Freenode.

Thanks again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants