Skip to content

Commit f0d0ee1

Browse files
committed
Merge pull request #587 from floreks/concurrent-api-calls
Make single API call to get events and filter them on backend
2 parents fc4df85 + 0d6e5bc commit f0d0ee1

File tree

5 files changed

+161
-117
lines changed

5 files changed

+161
-117
lines changed

src/app/backend/events.go

Lines changed: 6 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ package main
1717
import (
1818
"log"
1919

20-
api "k8s.io/kubernetes/pkg/api"
20+
"k8s.io/kubernetes/pkg/api"
2121
"k8s.io/kubernetes/pkg/api/unversioned"
2222
client "k8s.io/kubernetes/pkg/client/unversioned"
2323
"k8s.io/kubernetes/pkg/fields"
@@ -142,54 +142,18 @@ func GetReplicationControllerPodsEvents(client *client.Client, namespace, replic
142142
return nil, err
143143
}
144144

145-
events, err := GetPodsEvents(client, pods)
146-
147-
if err != nil {
148-
return nil, err
149-
}
150-
151-
return events, nil
152-
}
153-
154-
// GetPodsEvents gets events associated to given list of pods
155-
// TODO(floreks): refactor this to make single API call instead of N api calls
156-
func GetPodsEvents(client *client.Client, pods *api.PodList) ([]api.Event, error) {
157-
events := make([]api.Event, 0, 0)
158-
159-
for _, pod := range pods.Items {
160-
list, err := GetPodEvents(client, pod)
161-
162-
if err != nil {
163-
return nil, err
164-
}
165-
166-
for _, event := range list.Items {
167-
events = append(events, event)
168-
}
169-
170-
}
171-
172-
return events, nil
173-
}
174-
175-
// GetPodEvents gets events associated to given pod
176-
func GetPodEvents(client client.Interface, pod api.Pod) (*api.EventList, error) {
177-
fieldSelector, err := fields.ParseSelector("involvedObject.name=" + pod.Name)
178-
179-
if err != nil {
180-
return nil, err
181-
}
182-
183-
list, err := client.Events(pod.Namespace).List(api.ListOptions{
145+
eventList, err := client.Events(namespace).List(api.ListOptions{
184146
LabelSelector: labels.Everything(),
185-
FieldSelector: fieldSelector,
147+
FieldSelector: fields.Everything(),
186148
})
187149

188150
if err != nil {
189151
return nil, err
190152
}
191153

192-
return list, nil
154+
events := filterEventsByPodsUID(eventList.Items, pods.Items)
155+
156+
return events, nil
193157
}
194158

195159
// AppendEvents appends events from source slice to target events representation.

src/app/backend/eventscommon.go

Lines changed: 51 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ package main
1616

1717
import (
1818
"k8s.io/kubernetes/pkg/api"
19-
client "k8s.io/kubernetes/pkg/client/unversioned"
20-
"log"
19+
"k8s.io/kubernetes/pkg/types"
2120
"strings"
2221
)
2322

@@ -30,48 +29,73 @@ import (
3029
var FailedReasonPartials = []string{"failed", "err", "exceeded", "invalid", "unhealthy",
3130
"mismatch", "insufficient", "conflict", "outof", "nil"}
3231

33-
// GetPodsEventWarnings returns warning pod events based on given list of pods.
32+
// GetPodsEventWarnings returns warning pod events by filtering out events targeting only given pods
3433
// TODO(floreks) : Import and use Set instead of custom function to get rid of duplicates
35-
func GetPodsEventWarnings(client client.Interface, pods []api.Pod) (result []Event, err error) {
34+
func GetPodsEventWarnings(eventList *api.EventList, pods []api.Pod) []Event {
35+
result := make([]Event, 0)
36+
if eventList == nil {
37+
return result
38+
}
39+
40+
// Filter out only warning events
41+
events := getWarningEvents(eventList)
42+
failedPods := make([]api.Pod, 0)
43+
44+
// Filter out only 'failed' pods
3645
for _, pod := range pods {
3746
if !isRunningOrSucceeded(pod) {
38-
log.Printf("Getting warning events from pod: %s", pod.Name)
39-
events, err := GetPodEvents(client, pod)
47+
failedPods = append(failedPods, pod)
48+
}
49+
}
4050

41-
if err != nil {
42-
return nil, err
43-
}
51+
// Filter events by failed pods UID
52+
events = filterEventsByPodsUID(events, failedPods)
53+
events = removeDuplicates(events)
4454

45-
result = getPodsEventWarnings(events)
46-
}
55+
for _, event := range events {
56+
result = append(result, Event{
57+
Message: event.Message,
58+
Reason: event.Reason,
59+
Type: event.Type,
60+
})
4761
}
4862

49-
return removeDuplicates(result), nil
63+
return result
5064
}
5165

52-
// Returns list of Pod Event model objects based on kubernetes API event list object
53-
// Event list object is filtered to get only warning events.
54-
func getPodsEventWarnings(eventList *api.EventList) []Event {
55-
result := make([]Event, 0)
66+
// Returns filtered list of event objects.
67+
// Events list is filtered to get only events targeting pods on the list.
68+
func filterEventsByPodsUID(events []api.Event, pods []api.Pod) []api.Event {
69+
result := make([]api.Event, 0)
70+
podEventMap := make(map[types.UID]bool, 0)
5671

57-
var events []api.Event
58-
if !isTypeFilled(eventList.Items) {
59-
eventList.Items = fillEventsType(eventList.Items)
72+
if len(pods) == 0 || len(events) == 0 {
73+
return result
6074
}
6175

62-
events = filterEventsByType(eventList.Items, api.EventTypeWarning)
76+
for _, pod := range pods {
77+
podEventMap[pod.UID] = true
78+
}
6379

6480
for _, event := range events {
65-
result = append(result, Event{
66-
Message: event.Message,
67-
Reason: event.Reason,
68-
Type: event.Type,
69-
})
81+
if _, exists := podEventMap[event.InvolvedObject.UID]; exists {
82+
result = append(result, event)
83+
}
7084
}
7185

7286
return result
7387
}
7488

89+
// Returns filtered list of event objects.
90+
// Event list object is filtered to get only warning events.
91+
func getWarningEvents(eventList *api.EventList) []api.Event {
92+
if !isTypeFilled(eventList.Items) {
93+
eventList.Items = fillEventsType(eventList.Items)
94+
}
95+
96+
return filterEventsByType(eventList.Items, api.EventTypeWarning)
97+
}
98+
7599
// Filters kubernetes API event objects based on event type.
76100
// Empty string will return all events.
77101
func filterEventsByType(events []api.Event, eventType string) []api.Event {
@@ -131,9 +155,9 @@ func fillEventsType(events []api.Event) []api.Event {
131155
}
132156

133157
// Removes duplicate strings from the slice
134-
func removeDuplicates(slice []Event) []Event {
158+
func removeDuplicates(slice []api.Event) []api.Event {
135159
visited := make(map[string]bool, 0)
136-
result := make([]Event, 0)
160+
result := make([]api.Event, 0)
137161

138162
for _, elem := range slice {
139163
if !visited[elem.Reason] {

src/app/backend/replicationcontrollerlist.go

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import (
2525
)
2626

2727
// GetPodsEventWarningsFunc is a callback function used to get the pod status errors.
28-
type GetPodsEventWarningsFunc func(pods []api.Pod) ([]Event, error)
28+
type GetPodsEventWarningsFunc func(pods []api.Pod) []Event
2929

3030
// GetNodeFunc is a callback function used to get nodes by names.
3131
type GetNodeFunc func(nodeName string) (*api.Node, error)
@@ -94,17 +94,20 @@ func GetReplicationControllerList(client *client.Client) (*ReplicationController
9494
return nil, err
9595
}
9696

97+
eventsList, err := client.Events(api.NamespaceAll).List(api.ListOptions{
98+
LabelSelector: labels.Everything(),
99+
FieldSelector: fields.Everything(),
100+
})
101+
102+
if err != nil {
103+
return nil, err
104+
}
105+
97106
// Anonymous callback function to get pods warnings.
98107
// Function fulfils GetPodsEventWarningsFunc type contract.
99108
// Based on list of api pods returns list of pod related warning events
100-
getPodsEventWarningsFn := func(pods []api.Pod) ([]Event, error) {
101-
errors, err := GetPodsEventWarnings(client, pods)
102-
103-
if err != nil {
104-
return nil, err
105-
}
106-
107-
return errors, nil
109+
getPodsEventWarningsFn := func(pods []api.Pod) []Event {
110+
return GetPodsEventWarnings(eventsList, pods)
108111
}
109112

110113
// Anonymous callback function to get nodes by their names.
@@ -155,11 +158,7 @@ func getReplicationControllerList(replicationControllers []api.ReplicationContro
155158
}
156159
}
157160
podInfo := getReplicationControllerPodInfo(&replicationController, matchingPods)
158-
podErrors, err := getPodsEventWarningsFn(matchingPods)
159-
160-
if err != nil {
161-
return nil, err
162-
}
161+
podErrors := getPodsEventWarningsFn(matchingPods)
163162

164163
podInfo.Warnings = podErrors
165164

0 commit comments

Comments
 (0)