github.com/johnnyeven/libtools@v0.0.0-20191126065708-61829c1adf46/courier/router.go (about)

     1  package courier
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  
     7  	"github.com/sirupsen/logrus"
     8  )
     9  
    10  type IServe interface {
    11  	Serve(router *Router) error
    12  }
    13  
    14  func Run(router *Router, serves ...IServe) {
    15  	errs := make(chan error)
    16  
    17  	for i := range serves {
    18  		s := serves[i]
    19  		go func() {
    20  			if err := s.Serve(router); err != nil {
    21  				errs <- err
    22  			}
    23  		}()
    24  	}
    25  
    26  	select {
    27  	case err := <-errs:
    28  		logrus.Errorf("%s", err.Error())
    29  	}
    30  }
    31  
    32  type Router struct {
    33  	operators []IOperator
    34  	parent    *Router
    35  	children  map[*Router]bool
    36  }
    37  
    38  func NewRouter(operators ...IOperator) *Router {
    39  	return &Router{
    40  		operators: operators,
    41  	}
    42  }
    43  
    44  func (router *Router) Register(r *Router) {
    45  	if router.children == nil {
    46  		router.children = map[*Router]bool{}
    47  	}
    48  	r.parent = router
    49  	router.children[r] = true
    50  }
    51  
    52  func (router *Router) Route() *Route {
    53  	parent := router.parent
    54  	operators := router.operators
    55  
    56  	for parent != nil {
    57  		operators = append(parent.operators, operators...)
    58  		parent = parent.parent
    59  	}
    60  
    61  	return &Route{
    62  		last:      router.children == nil,
    63  		Operators: operators,
    64  	}
    65  }
    66  
    67  func (router *Router) Routes() (routes []*Route) {
    68  	for child := range router.children {
    69  		route := child.Route()
    70  		if route.last && len(route.Operators) > 0 {
    71  			routes = append(routes, route)
    72  		}
    73  		if child.children != nil {
    74  			routes = append(routes, child.Routes()...)
    75  		}
    76  	}
    77  	return
    78  }
    79  
    80  type Route struct {
    81  	Operators []IOperator
    82  	last      bool
    83  }
    84  
    85  func (route *Route) EffectiveOperators() (operators []IOperator, operatorTypeNames []string) {
    86  	for _, operator := range route.Operators {
    87  		if _, isEmptyOperator := operator.(IEmptyOperator); !isEmptyOperator {
    88  			operatorType := reflect.TypeOf(operator)
    89  			modify := ""
    90  			if stringer, ok := operator.(fmt.Stringer); ok {
    91  				modify = stringer.String()
    92  			}
    93  			if operatorType.Kind() == reflect.Ptr {
    94  				operatorTypeNames = append(operatorTypeNames, "*"+operatorType.Elem().Name()+modify)
    95  			} else {
    96  				operatorTypeNames = append(operatorTypeNames, operatorType.Name()+modify)
    97  			}
    98  			operators = append(operators, operator)
    99  		}
   100  	}
   101  	return
   102  }