github.com/moleculer-go/moleculer@v0.3.3/middleware/middleware.go (about)

     1  package middleware
     2  
     3  import (
     4  	"github.com/moleculer-go/moleculer"
     5  	log "github.com/sirupsen/logrus"
     6  )
     7  
     8  type AfterActionParams struct {
     9  	BrokerContext moleculer.BrokerContext
    10  	Result        moleculer.Payload
    11  }
    12  
    13  type Dispatch struct {
    14  	handlers map[string][]moleculer.MiddlewareHandler
    15  	logger   *log.Entry
    16  }
    17  
    18  func Dispatcher(logger *log.Entry) *Dispatch {
    19  	handlers := make(map[string][]moleculer.MiddlewareHandler)
    20  	return &Dispatch{handlers, logger}
    21  }
    22  
    23  var validHandlers = []string{"Config", "brokerStopping", "brokerStopped", "brokerStarting", "brokerStarted", "serviceStopping", "serviceStopped", "serviceStarting", "serviceStarted", "beforeLocalAction", "afterLocalAction", "beforeRemoteAction", "afterRemoteAction"}
    24  
    25  // validHandler check if the name of handlers midlewares are tryignt o register exists!
    26  func (dispatch *Dispatch) validHandler(name string) bool {
    27  	for _, item := range validHandlers {
    28  		if name == item {
    29  			return true
    30  		}
    31  	}
    32  	return false
    33  }
    34  
    35  func (dispatch *Dispatch) Add(mwares moleculer.Middlewares) {
    36  	for name, handler := range mwares {
    37  		if dispatch.validHandler(name) {
    38  			dispatch.handlers[name] = append(dispatch.handlers[name], handler)
    39  		}
    40  	}
    41  }
    42  
    43  func (dispatch *Dispatch) Has(name string) bool {
    44  	items, exists := dispatch.handlers[name]
    45  	return exists && len(items) > 0
    46  }
    47  
    48  // nextHandler return a next function that invoke next midlewares until the end of the stack.
    49  func nextHandler(handlers *[]moleculer.MiddlewareHandler, index *int, params interface{}, resultChanel chan interface{}) func(result ...interface{}) {
    50  	return func(newResult ...interface{}) {
    51  		newIndex := (*index) + 1
    52  		index = &newIndex
    53  		if newIndex < len((*handlers)) {
    54  			var value interface{}
    55  			if newResult != nil && len(newResult) > 0 {
    56  				value = newResult[0]
    57  			} else {
    58  				value = params
    59  			}
    60  			(*handlers)[newIndex](value, nextHandler(handlers, index, value, resultChanel))
    61  		} else {
    62  			if newResult != nil && len(newResult) > 0 {
    63  				resultChanel <- newResult[0]
    64  			} else {
    65  				resultChanel <- params
    66  			}
    67  		}
    68  	}
    69  }
    70  
    71  // CallHandlers invoke handlers that subscribe to this topic.
    72  func (dispatch *Dispatch) CallHandlers(name string, params interface{}) interface{} {
    73  	handlers := dispatch.handlers[name]
    74  	if len(handlers) > 0 {
    75  		result := make(chan interface{})
    76  		index := 0
    77  		go func() {
    78  			//starts the chain reaction ...
    79  			handlers[0](params, nextHandler(&handlers, &index, params, result))
    80  		}()
    81  		return <-result
    82  	} else {
    83  		dispatch.logger.Trace("No Handlers found for -> ", name)
    84  	}
    85  	return params
    86  }