func (p *AfterChannel) PushFront(h AfterHandlerTempl) {
	Handlers := make([]AfterHandlerTempl, len(p.Handlers)+1)
	Handlers[0] = h
	copy(Handlers[1:], p.Handlers)
	p.Handlers = Handlers
}
PushFront should not be used after pitaya is running
package pipeline
import (
	"context"
	"github.com/topfreegames/pitaya/v2/logger"
)
type (
	HandlerTempl func(ctx context.Context, in interface{}) (c context.Context, out interface{}, err error)
	AfterHandlerTempl func(ctx context.Context, out interface{}, err error) (interface{}, error)
	Channel struct {
		Handlers []HandlerTempl
	}
	AfterChannel struct {
		Handlers []AfterHandlerTempl
	}
	HandlerHooks struct {
		BeforeHandler *Channel
		AfterHandler  *AfterChannel
	}
)
func NewHandlerHooks() *HandlerHooks {
	return &HandlerHooks{
		BeforeHandler: NewChannel(),
		AfterHandler:  NewAfterChannel(),
	}
}
func NewChannel() *Channel {
	return &Channel{Handlers: []HandlerTempl{}}
}
func NewAfterChannel() *AfterChannel {
	return &AfterChannel{Handlers: []AfterHandlerTempl{}}
}
func (p *Channel) ExecuteBeforePipeline(ctx context.Context, data interface{}) (context.Context, interface{}, error) {
	var err error
	res := data
	if len(p.Handlers) > 0 {
		for _, h := range p.Handlers {
			ctx, res, err = h(ctx, res)
			if err != nil {
				logger.Log.Debugf("pitaya/handler: broken pipeline: %s", err.Error())
				return ctx, res, err
			}
		}
	}
	return ctx, res, nil
}
func (p *AfterChannel) ExecuteAfterPipeline(ctx context.Context, res interface{}, err error) (interface{}, error) {
	ret := res
	if len(p.Handlers) > 0 {
		for _, h := range p.Handlers {
			ret, err = h(ctx, ret, err)
		}
	}
	return ret, err
}
func (p *Channel) PushFront(h HandlerTempl) {
	Handlers := make([]HandlerTempl, len(p.Handlers)+1)
	Handlers[0] = h
	copy(Handlers[1:], p.Handlers)
	p.Handlers = Handlers
}
func (p *Channel) PushBack(h HandlerTempl) {
	p.Handlers = append(p.Handlers, h)
}
func (p *Channel) Clear() {
	p.Handlers = make([]HandlerTempl, 0)
}