diff --git a/events/handler.go b/events/handler.go index 8357a026..48886b18 100644 --- a/events/handler.go +++ b/events/handler.go @@ -25,64 +25,28 @@ import ( info "github.com/google/cadvisor/info/v1" ) -// EventManager is implemented by Events. It provides two ways to monitor -// events and one way to add events -type EventManager interface { - // Watch checks if events fed to it by the caller of AddEvent satisfy the - // request and if so sends the event back to the caller on outChannel - WatchEvents(request *Request) (*EventChannel, error) - // GetEvents() returns a slice of all events detected that have passed - // the *Request object parameters to the caller - GetEvents(request *Request) (EventSlice, error) - // AddEvent allows the caller to add an event to an EventManager - // object - AddEvent(e *info.Event) error - // Removes a watch instance from the EventManager's watchers map - StopWatch(watch_id int) -} - -// Events holds a slice of *Event objects with a potential field -// that caps the number of events held. It is an implementation of the -// EventManager interface -type events struct { - // eventlist holds the complete set of events found over an - // EventManager events instantiation. - eventlist EventSlice - // the slice of watch pointers allows the EventManager access to channels - // linked to different calls of WatchEvents. When new events are found that - // satisfy the request of a given watch object in watchers, the event - // is sent over the channel to that caller of WatchEvents - watchers map[int]*watch - // lock that blocks eventlist from being accessed until a writer releases it - eventsLock sync.RWMutex - // lock that blocks watchers from being accessed until a writer releases it - watcherLock sync.RWMutex - // receives notices when a watch event ends and needs to be removed from - // the watchers list - lastId int -} - -// initialized by a call to WatchEvents(), a watch struct will then be added -// to the events slice of *watch objects. When AddEvent() finds an event that -// satisfies the request parameter of a watch object in events.watchers, -// it will send that event out over the watch object's channel. The caller that -// called WatchEvents will receive the event over the channel provided to -// WatchEvents -type watch struct { - // request specifies all the parameters that events sent through the - // channel must satisfy. Specified by the creator of the watch object - request *Request - // a channel created by the caller through which events satisfying the - // request are sent to the caller - eventChannel *EventChannel - // unique identifier of a watch that is used as a key in events' watchers - // map - id int -} - -// typedef of a slice of Event pointers type EventSlice []*info.Event +// functions necessary to implement the sort interface on the Events struct +func (e EventSlice) Len() int { + return len(e) +} + +func (e EventSlice) Swap(i, j int) { + e[i], e[j] = e[j], e[i] +} + +func (e EventSlice) Less(i, j int) bool { + return e[i].Timestamp.Before(e[j].Timestamp) +} + +type EventChannel struct { + // Watch ID. Can be used by the caller to request cancellation of watch events. + watchId int + // Channel on which the caller can receive watch events. + channel chan *info.Event +} + // Request holds a set of parameters by which Event objects may be screened. // The caller may want events that occurred within a specific timeframe // or of a certain type, which may be specified in the *Request object @@ -97,7 +61,7 @@ type Request struct { // EventType is a map that specifies the type(s) of events wanted EventType map[info.EventType]bool // allows the caller to put a limit on how many - // events they receive. If there are more events than MaxEventsReturned + // events to receive. If there are more events than MaxEventsReturned // then the most chronologically recent events in the time period // specified are returned. Must be >= 1 MaxEventsReturned int @@ -108,9 +72,50 @@ type Request struct { IncludeSubcontainers bool } -type EventChannel struct { - watchId int - channel chan *info.Event +// EventManager is implemented by Events. It provides two ways to monitor +// events and one way to add events +type EventManager interface { + // WatchEvents() allows a caller to register for receiving events based on the specified request. + // On successful registration, an EventChannel object is returned. + WatchEvents(request *Request) (*EventChannel, error) + // GetEvents() returns all detected events based on the filters specified in request. + GetEvents(request *Request) (EventSlice, error) + // AddEvent allows the caller to add an event to an EventManager + // object + AddEvent(e *info.Event) error + // Cancels a previously requested watch event. + StopWatch(watch_id int) +} + +// events provides an implementation for the EventManager interface. +type events struct { + // eventList holds the complete set of events found over an + // EventManager events instantiation. + eventList EventSlice + // map of registered watchers keyed by watch id. + watchers map[int]*watch + // lock guarding the eventList. + eventsLock sync.RWMutex + // lock guarding watchers. + watcherLock sync.RWMutex + // last allocated watch id. + lastId int +} + +// initialized by a call to WatchEvents(), a watch struct will then be added +// to the events slice of *watch objects. When AddEvent() finds an event that +// satisfies the request parameter of a watch object in events.watchers, +// it will send that event out over the watch object's channel. The caller that +// called WatchEvents will receive the event over the channel provided to +// WatchEvents +type watch struct { + // request parameters passed in by the caller of WatchEvents() + request *Request + // a channel used to send event back to the caller. + eventChannel *EventChannel + // unique identifier of a watch that is used as a key in events' watchers + // map + id int } func NewEventChannel(watchId int) *EventChannel { @@ -123,7 +128,7 @@ func NewEventChannel(watchId int) *EventChannel { // returns a pointer to an initialized Events object func NewEventManager() *events { return &events{ - eventlist: make(EventSlice, 0), + eventList: make(EventSlice, 0), watchers: make(map[int]*watch), } } @@ -153,21 +158,6 @@ func (self *EventChannel) GetWatchId() int { return self.watchId } -// function necessary to implement the sort interface on the Events struct -func (e EventSlice) Len() int { - return len(e) -} - -// function necessary to implement the sort interface on the Events struct -func (e EventSlice) Swap(i, j int) { - e[i], e[j] = e[j], e[i] -} - -// function necessary to implement the sort interface on the Events struct -func (e EventSlice) Less(i, j int) bool { - return e[i].Timestamp.Before(e[j].Timestamp) -} - // sorts and returns up to the last MaxEventsReturned chronological elements func getMaxEventsReturned(request *Request, eSlice EventSlice) EventSlice { sort.Sort(eSlice) @@ -213,7 +203,7 @@ func checkIfEventSatisfiesRequest(request *Request, event *info.Event) bool { return true } -// method of Events object that screens Event objects found in the eventlist +// method of Events object that screens Event objects found in the eventList // attribute and if they fit the parameters passed by the Request object, // adds it to a slice of *Event objects that is returned. If both MaxEventsReturned // and StartTime/EndTime are specified in the request object, then only @@ -222,7 +212,7 @@ func (self *events) GetEvents(request *Request) (EventSlice, error) { returnEventList := EventSlice{} self.eventsLock.RLock() defer self.eventsLock.RUnlock() - for _, e := range self.eventlist { + for _, e := range self.eventList { if checkIfEventSatisfiesRequest(request, e) { returnEventList = append(returnEventList, e) } @@ -251,11 +241,11 @@ func (self *events) WatchEvents(request *Request) (*EventChannel, error) { return returnEventChannel, nil } -// helper function to update the event manager's eventlist +// helper function to update the event manager's eventList func (self *events) updateEventList(e *info.Event) { self.eventsLock.Lock() defer self.eventsLock.Unlock() - self.eventlist = append(self.eventlist, e) + self.eventList = append(self.eventList, e) } func (self *events) findValidWatchers(e *info.Event) []*watch { @@ -270,7 +260,7 @@ func (self *events) findValidWatchers(e *info.Event) []*watch { } // method of Events object that adds the argument Event object to the -// eventlist. It also feeds the event to a set of watch channels +// eventList. It also feeds the event to a set of watch channels // held by the manager if it satisfies the request keys of the channels func (self *events) AddEvent(e *info.Event) error { self.updateEventList(e) diff --git a/events/handler_test.go b/events/handler_test.go index d11b4b9b..e1336e91 100644 --- a/events/handler_test.go +++ b/events/handler_test.go @@ -139,8 +139,8 @@ func TestAddEventAddsEventsToEventManager(t *testing.T) { myEventHolder.AddEvent(fakeEvent) - checkNumberOfEvents(t, 1, myEventHolder.eventlist.Len()) - ensureProperEventReturned(t, fakeEvent, myEventHolder.eventlist[0]) + checkNumberOfEvents(t, 1, myEventHolder.eventList.Len()) + ensureProperEventReturned(t, fakeEvent, myEventHolder.eventList[0]) } func TestGetEventsForOneEvent(t *testing.T) {