From 5c8d7a7caca2b37317549c023a103a7563ef0e4f Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Mon, 15 Jan 2018 22:08:13 -0700 Subject: [PATCH 1/3] Handle non-nil interfaces with nil values --- condition/condition.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/condition/condition.go b/condition/condition.go index 502361978..882ac8d62 100644 --- a/condition/condition.go +++ b/condition/condition.go @@ -83,7 +83,7 @@ func (c Cond) Once(obj runtime.Object, f func() (runtime.Object, error)) (runtim c.Unknown(obj) newObj, err := f() - if newObj != nil { + if newObj != nil && !reflect.ValueOf(newObj).IsNil() { obj = newObj } @@ -103,7 +103,7 @@ func (c Cond) DoUntilTrue(obj runtime.Object, f func() (runtime.Object, error)) c.Unknown(obj) newObj, err := f() - if newObj != nil { + if newObj != nil && !reflect.ValueOf(newObj).IsNil() { obj = newObj } @@ -124,7 +124,7 @@ func (c Cond) Do(obj runtime.Object, f func() (runtime.Object, error)) (runtime. func (c Cond) do(obj runtime.Object, f func() (runtime.Object, error)) (runtime.Object, error) { c.Unknown(obj) newObj, err := f() - if newObj != nil { + if newObj != nil && !reflect.ValueOf(newObj).IsNil() { obj = newObj } From c04b4bf7d5849b753fc166037b52016cffd92fe4 Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Mon, 15 Jan 2018 22:08:26 -0700 Subject: [PATCH 2/3] Don't generate the ID field --- generator/generator.go | 3 +++ types/types.go | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/generator/generator.go b/generator/generator.go index 8137a0d33..6e3a5238b 100644 --- a/generator/generator.go +++ b/generator/generator.go @@ -101,6 +101,9 @@ func getTypeString(nullable bool, typeName string, schema *types.Schema, schemas func getTypeMap(schema *types.Schema, schemas *types.Schemas) map[string]fieldInfo { result := map[string]fieldInfo{} for name, field := range schema.ResourceFields { + if strings.EqualFold(name, "id") { + continue + } result[field.CodeName] = fieldInfo{ Name: name, Type: getGoType(field, schema, schemas), diff --git a/types/types.go b/types/types.go index a1421d6ff..f4601938b 100644 --- a/types/types.go +++ b/types/types.go @@ -1,5 +1,9 @@ package types +const ( + ResourceFieldID = "id" +) + type Collection struct { Type string `json:"type,omitempty"` Links map[string]string `json:"links"` From eff44adb4638ab4af708ae1b6a827dd6617fc45d Mon Sep 17 00:00:00 2001 From: Darren Shepherd Date: Mon, 15 Jan 2018 22:08:36 -0700 Subject: [PATCH 3/3] Add name to handlers --- controller/generic_controller.go | 50 +++++++++++++++++++++++++------- generator/controller_template.go | 14 ++++----- 2 files changed, 47 insertions(+), 17 deletions(-) diff --git a/controller/generic_controller.go b/controller/generic_controller.go index 434ab136f..c7e2ef054 100644 --- a/controller/generic_controller.go +++ b/controller/generic_controller.go @@ -23,17 +23,22 @@ type HandlerFunc func(key string) error type GenericController interface { Informer() cache.SharedIndexInformer - AddHandler(handler HandlerFunc) + AddHandler(name string, handler HandlerFunc) HandlerCount() int Enqueue(namespace, name string) Sync(ctx context.Context) error Start(ctx context.Context, threadiness int) error } +type handlerDef struct { + name string + handler HandlerFunc +} + type genericController struct { sync.Mutex informer cache.SharedIndexInformer - handlers []HandlerFunc + handlers []handlerDef queue workqueue.RateLimitingInterface name string running bool @@ -72,8 +77,11 @@ func (g *genericController) Enqueue(namespace, name string) { } } -func (g *genericController) AddHandler(handler HandlerFunc) { - g.handlers = append(g.handlers, handler) +func (g *genericController) AddHandler(name string, handler HandlerFunc) { + g.handlers = append(g.handlers, handlerDef{ + name: name, + handler: handler, + }) } func (g *genericController) Sync(ctx context.Context) error { @@ -162,23 +170,45 @@ func (g *genericController) processNextWorkItem() bool { // do your work on the key. This method will contains your "do stuff" logic err := g.syncHandler(key.(string)) - if _, ok := err.(*ForgetError); err == nil || ok { + checkErr := err + if handlerErr, ok := checkErr.(*handlerError); ok { + checkErr = handlerErr.err + } + if _, ok := checkErr.(*ForgetError); err == nil || ok { + if ok { + logrus.Infof("%v %v completed with dropped err: %v", g.name, key, err) + } g.queue.Forget(key) return true } - utilruntime.HandleError(fmt.Errorf("%v %v failed with : %v", g.name, key, err)) + utilruntime.HandleError(fmt.Errorf("%v %v %v", g.name, key, err)) g.queue.AddRateLimited(key) return true } -func (g *genericController) syncHandler(s string) error { +func (g *genericController) syncHandler(s string) (err error) { + defer utilruntime.RecoverFromPanic(&err) + var errs []error for _, handler := range g.handlers { - if err := handler(s); err != nil { - errs = append(errs, err) + if err := handler.handler(s); err != nil { + errs = append(errs, &handlerError{ + name: handler.name, + err: err, + }) } } - return types.NewErrors(errs) + err = types.NewErrors(errs) + return +} + +type handlerError struct { + name string + err error +} + +func (h *handlerError) Error() string { + return fmt.Sprintf("[%s] failed with : %v", h.name, h.err) } diff --git a/generator/controller_template.go b/generator/controller_template.go index 15f236ec7..214813789 100644 --- a/generator/controller_template.go +++ b/generator/controller_template.go @@ -51,7 +51,7 @@ type {{.schema.CodeName}}Lister interface { type {{.schema.CodeName}}Controller interface { Informer() cache.SharedIndexInformer Lister() {{.schema.CodeName}}Lister - AddHandler(handler {{.schema.CodeName}}HandlerFunc) + AddHandler(name string, handler {{.schema.CodeName}}HandlerFunc) Enqueue(namespace, name string) Sync(ctx context.Context) error Start(ctx context.Context, threadiness int) error @@ -69,7 +69,7 @@ type {{.schema.CodeName}}Interface interface { Watch(opts metav1.ListOptions) (watch.Interface, error) DeleteCollection(deleteOpts *metav1.DeleteOptions, listOpts metav1.ListOptions) error Controller() {{.schema.CodeName}}Controller - AddSyncHandler(sync {{.schema.CodeName}}HandlerFunc) + AddHandler(name string, sync {{.schema.CodeName}}HandlerFunc) AddLifecycle(name string, lifecycle {{.schema.CodeName}}Lifecycle) } @@ -115,8 +115,8 @@ func (c *{{.schema.ID}}Controller) Lister() {{.schema.CodeName}}Lister { } -func (c *{{.schema.ID}}Controller) AddHandler(handler {{.schema.CodeName}}HandlerFunc) { - c.GenericController.AddHandler(func(key string) error { +func (c *{{.schema.ID}}Controller) AddHandler(name string, handler {{.schema.CodeName}}HandlerFunc) { + c.GenericController.AddHandler(name, func(key string) error { obj, exists, err := c.Informer().GetStore().GetByKey(key) if err != nil { return err @@ -219,12 +219,12 @@ func (s *{{.schema.ID}}Client) DeleteCollection(deleteOpts *metav1.DeleteOptions return s.objectClient.DeleteCollection(deleteOpts, listOpts) } -func (s *{{.schema.ID}}Client) AddSyncHandler(sync {{.schema.CodeName}}HandlerFunc) { - s.Controller().AddHandler(sync) +func (s *{{.schema.ID}}Client) AddHandler(name string, sync {{.schema.CodeName}}HandlerFunc) { + s.Controller().AddHandler(name, sync) } func (s *{{.schema.ID}}Client) AddLifecycle(name string, lifecycle {{.schema.CodeName}}Lifecycle) { sync := New{{.schema.CodeName}}LifecycleAdapter(name, s, lifecycle) - s.AddSyncHandler(sync) + s.AddHandler(name, sync) } `