@@ -21,6 +21,7 @@ import (
21
21
"fmt"
22
22
"reflect"
23
23
"strings"
24
+ "time"
24
25
25
26
apimeta "k8s.io/apimachinery/pkg/api/meta"
26
27
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
@@ -57,7 +58,12 @@ func (ip *informerCache) Get(ctx context.Context, key client.ObjectKey, out runt
57
58
return err
58
59
}
59
60
60
- started , cache , err := ip .InformersMap .Get (gvk , out )
61
+ ctx , cancelFunc := addTimeout (ctx )
62
+ if cancelFunc != nil {
63
+ defer cancelFunc ()
64
+ }
65
+ cache , err := ip .InformersMap .Get (ctx , gvk , out )
66
+ started , cache , err := ip .InformersMap .Get (ctx , gvk , out )
61
67
if err != nil {
62
68
return err
63
69
}
@@ -101,7 +107,11 @@ func (ip *informerCache) List(ctx context.Context, out runtime.Object, opts ...c
101
107
}
102
108
}
103
109
104
- started , cache , err := ip .InformersMap .Get (gvk , cacheTypeObj )
110
+ ctx , cancelFunc := addTimeout (ctx )
111
+ if cancelFunc != nil {
112
+ defer cancelFunc ()
113
+ }
114
+ started , cache , err := ip .InformersMap .Get (ctx , gvk , cacheTypeObj )
105
115
if err != nil {
106
116
return err
107
117
}
@@ -113,27 +123,47 @@ func (ip *informerCache) List(ctx context.Context, out runtime.Object, opts ...c
113
123
return cache .Reader .List (ctx , out , opts ... )
114
124
}
115
125
126
+ // addTimeout adds a default 30 second timeout to a child contxt
127
+ // if one does not exist.
128
+ func addTimeout (ctx context.Context ) (context.Context , context.CancelFunc ) {
129
+ var cancelFunc context.CancelFunc
130
+ if _ , ok := ctx .Deadline (); ! ok {
131
+ ctx , cancelFunc = context .WithTimeout (ctx , 30 * time .Second )
132
+ }
133
+ return ctx , cancelFunc
134
+ }
135
+
116
136
// GetInformerForKind returns the informer for the GroupVersionKind
137
+ // Will timeout after 30 seconds if the informer is new and can not be
138
+ // synced.
117
139
func (ip * informerCache ) GetInformerForKind (gvk schema.GroupVersionKind ) (Informer , error ) {
118
140
// Map the gvk to an object
119
141
obj , err := ip .Scheme .New (gvk )
120
142
if err != nil {
121
143
return nil , err
122
144
}
123
- _ , i , err := ip .InformersMap .Get (gvk , obj )
145
+ ctx , cancelFunc := addTimeout (context .TODO ())
146
+ // There will never be a nil cancelFunc
147
+ defer cancelFunc ()
148
+ _ , i , err := ip .InformersMap .Get (ctx , gvk , obj )
124
149
if err != nil {
125
150
return nil , err
126
151
}
127
152
return i .Informer , err
128
153
}
129
154
130
155
// GetInformer returns the informer for the obj
156
+ // Will timeout after 30 seconds if the informer is new and can not be
157
+ // synced.
131
158
func (ip * informerCache ) GetInformer (obj runtime.Object ) (Informer , error ) {
132
159
gvk , err := apiutil .GVKForObject (obj , ip .Scheme )
133
160
if err != nil {
134
161
return nil , err
135
162
}
136
- _ , i , err := ip .InformersMap .Get (gvk , obj )
163
+ ctx , cancelFunc := addTimeout (context .TODO ())
164
+ // There will never be a nil cancelFunc
165
+ defer cancelFunc ()
166
+ _ , i , err := ip .InformersMap .Get (ctx , gvk , obj )
137
167
if err != nil {
138
168
return nil , err
139
169
}
0 commit comments