add route methods on Notifiability

This commit is contained in:
c9s 2020-10-27 09:24:59 +08:00
parent ea05d998f2
commit 42f947506c
4 changed files with 67 additions and 8 deletions

View File

@ -17,6 +17,21 @@ func (n *NullNotifier) Notify(format string, args ...interface{}) error {
type Notifiability struct { type Notifiability struct {
notifiers []Notifier notifiers []Notifier
sessionChannelRouter *PatternChannelRouter
symbolChannelRouter *PatternChannelRouter
objectChannelRouter *ObjectChannelRouter
}
func (m *Notifiability) RouteSymbol(symbol string) (channel string, ok bool) {
return m.symbolChannelRouter.Route(symbol)
}
func (m *Notifiability) RouteSession(session string) (channel string, ok bool) {
return m.sessionChannelRouter.Route(session)
}
func (m *Notifiability) RouteObject(obj interface{}) (channel string, ok bool) {
return m.objectChannelRouter.Route(obj)
} }
func (m *Notifiability) AddNotifier(notifier Notifier) { func (m *Notifiability) AddNotifier(notifier Notifier) {

View File

@ -87,7 +87,17 @@ type PatternChannelRouter struct {
routes map[*regexp.Regexp]string routes map[*regexp.Regexp]string
} }
func (router *PatternChannelRouter) RouteSymbols(routes map[string]string) *PatternChannelRouter { func NewPatternChannelRouter(routes map[string]string) *PatternChannelRouter {
router := &PatternChannelRouter{
routes: make(map[*regexp.Regexp]string),
}
if routes != nil {
router.AddRoute(routes)
}
return router
}
func (router *PatternChannelRouter) AddRoute(routes map[string]string) *PatternChannelRouter {
for pattern, channel := range routes { for pattern, channel := range routes {
router.routes[regexp.MustCompile(pattern)] = channel router.routes[regexp.MustCompile(pattern)] = channel
} }
@ -95,7 +105,7 @@ func (router *PatternChannelRouter) RouteSymbols(routes map[string]string) *Patt
return router return router
} }
func (router *PatternChannelRouter) Dispatch(text string) (channel string, ok bool) { func (router *PatternChannelRouter) Route(text string) (channel string, ok bool) {
for pattern, channel := range router.routes { for pattern, channel := range router.routes {
if pattern.MatchString(text) { if pattern.MatchString(text) {
ok = true ok = true
@ -112,12 +122,16 @@ type ObjectChannelRouter struct {
routes []ObjectChannelHandler routes []ObjectChannelHandler
} }
func (router *ObjectChannelRouter) Route(f ObjectChannelHandler) *ObjectChannelRouter { func NewObjectChannelRouter() *ObjectChannelRouter {
return &ObjectChannelRouter{}
}
func (router *ObjectChannelRouter) AddRoute(f ObjectChannelHandler) *ObjectChannelRouter {
router.routes = append(router.routes, f) router.routes = append(router.routes, f)
return router return router
} }
func (router *ObjectChannelRouter) Dispatch(obj interface{}) (channel string, ok bool) { func (router *ObjectChannelRouter) Route(obj interface{}) (channel string, ok bool) {
for _, f := range router.routes { for _, f := range router.routes {
channel, ok = f(obj) channel, ok = f(obj)
if ok { if ok {

View File

@ -16,9 +16,9 @@ notifications:
# routing rules # routing rules
routing: routing:
trade: bySymbol trade: "$symbol"
order: bySymbol order: "$symbol"
submitOrder: byExchange submitOrder: "$session"
pnL: "#bbgo-pnl" pnL: "#bbgo-pnl"
sessions: sessions:

View File

@ -70,6 +70,36 @@ func runConfig(ctx context.Context, userConfig *bbgo.Config) error {
// configure notifiers // configure notifiers
notifierSet := &bbgo.Notifiability{} notifierSet := &bbgo.Notifiability{}
if conf := userConfig.Notifications; conf != nil {
// configure routing here
var symbolChannelRouter = bbgo.NewPatternChannelRouter(conf.SymbolChannels)
var sessionChannelRouter = bbgo.NewPatternChannelRouter(conf.SessionChannels)
var objectChannelRouter = bbgo.NewObjectChannelRouter()
_ = sessionChannelRouter
if conf.Routing != nil {
switch conf.Routing.Trade {
case "$session":
case "$symbol":
objectChannelRouter.Route(func(obj interface{}) (channel string, ok bool) {
if trade, matched := obj.(*types.Trade); matched {
if channel, ok = symbolChannelRouter.Route(trade.Symbol); ok {
return
}
}
return
})
default:
}
}
}
// for slack // for slack
slackToken := viper.GetString("slack-token") slackToken := viper.GetString("slack-token")
if len(slackToken) > 0 { if len(slackToken) > 0 {