From 562b1ab9b7364fa967571293d884892d1168138a Mon Sep 17 00:00:00 2001 From: Vasiliy Tolstov <v.tolstov@unistack.org> Date: Fri, 7 Mar 2025 15:26:20 +0300 Subject: [PATCH] broker: simplify handler check Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org> --- broker/broker.go | 2 +- broker/subscriber.go | 85 ++++---------------------------------------- 2 files changed, 7 insertions(+), 80 deletions(-) diff --git a/broker/broker.go b/broker/broker.go index 53b15d4e..3664433a 100644 --- a/broker/broker.go +++ b/broker/broker.go @@ -21,7 +21,7 @@ var ( // ErrInvalidMessage returns when invalid Message passed ErrInvalidMessage = errors.New("invalid message") // ErrInvalidHandler returns when subscriber passed to Subscribe - ErrInvalidHandler = errors.New("invalid handler") + ErrInvalidHandler = errors.New("invalid handler, ony func(Message) error and func([]Message) error supported") // DefaultGracefulTimeout DefaultGracefulTimeout = 5 * time.Second ) diff --git a/broker/subscriber.go b/broker/subscriber.go index bdced69c..df6f58a8 100644 --- a/broker/subscriber.go +++ b/broker/subscriber.go @@ -1,87 +1,14 @@ package broker -import ( - "fmt" - "reflect" - "unicode" - "unicode/utf8" -) - -const ( - messageSig = "func(broker.Message) error" - messagesSig = "func([]broker.Message) error" -) - -// Precompute the reflect type for error. Can't use error directly -// because Typeof takes an empty interface value. This is annoying. -var typeOfError = reflect.TypeOf((*error)(nil)).Elem() - -// Is this an exported - upper case - name? -func isExported(name string) bool { - r, _ := utf8.DecodeRuneInString(name) - return unicode.IsUpper(r) -} - -// Is this type exported or a builtin? -func isExportedOrBuiltinType(t reflect.Type) bool { - for t.Kind() == reflect.Ptr { - t = t.Elem() - } - // PkgPath will be non-empty even for an exported type, - // so we need to check the type name as well. - return isExported(t.Name()) || t.PkgPath() == "" -} - // IsValidHandler func signature func IsValidHandler(sub interface{}) error { - typ := reflect.TypeOf(sub) - var argType reflect.Type - switch typ.Kind() { - case reflect.Func: - name := "Func" - switch typ.NumIn() { - case 1: - argType = typ.In(0) - default: - return fmt.Errorf("subscriber %v takes wrong number of args: %v required signature %s", name, typ.NumIn(), messageSig) - } - if !isExportedOrBuiltinType(argType) { - return fmt.Errorf("subscriber %v argument type not exported: %v", name, argType) - } - if typ.NumOut() != 1 { - return fmt.Errorf("subscriber %v has wrong number of return values: %v require signature %s", - name, typ.NumOut(), messageSig) - } - if returnType := typ.Out(0); returnType != typeOfError { - return fmt.Errorf("subscriber %v returns %v not error", name, returnType.String()) - } + switch sub.(type) { default: - hdlr := reflect.ValueOf(sub) - name := reflect.Indirect(hdlr).Type().Name() - - for m := 0; m < typ.NumMethod(); m++ { - method := typ.Method(m) - switch method.Type.NumIn() { - case 3: - argType = method.Type.In(2) - default: - return fmt.Errorf("subscriber %v.%v takes wrong number of args: %v required signature %s", - name, method.Name, method.Type.NumIn(), messageSig) - } - - if !isExportedOrBuiltinType(argType) { - return fmt.Errorf("%v argument type not exported: %v", name, argType) - } - if method.Type.NumOut() != 1 { - return fmt.Errorf( - "subscriber %v.%v has wrong number of return values: %v require signature %s", - name, method.Name, method.Type.NumOut(), messageSig) - } - if returnType := method.Type.Out(0); returnType != typeOfError { - return fmt.Errorf("subscriber %v.%v returns %v not error", name, method.Name, returnType.String()) - } - } + return ErrInvalidHandler + case func(Message) error: + break + case func([]Message) error: + break } - return nil }