113 lines
2.2 KiB
Go
113 lines
2.2 KiB
Go
|
// Package router providers a default implement of `router` and `Route`.
|
||
|
package router
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"sync"
|
||
|
|
||
|
"git.hpds.cc/Component/network/frame"
|
||
|
herr "git.hpds.cc/Component/network/hpds_err"
|
||
|
"git.hpds.cc/Component/network/metadata"
|
||
|
)
|
||
|
|
||
|
// DefaultRouter providers a default implement of `router`,
|
||
|
// It routes the data according to obverse tag or connId.
|
||
|
type DefaultRouter struct {
|
||
|
r *defaultRoute
|
||
|
}
|
||
|
|
||
|
// Default return the DefaultRouter.
|
||
|
func Default(functions []string) Router {
|
||
|
return &DefaultRouter{r: newRoute(functions)}
|
||
|
}
|
||
|
|
||
|
// Route get route from metadata.
|
||
|
func (r *DefaultRouter) Route(metadata metadata.Metadata) Route {
|
||
|
return r.r
|
||
|
}
|
||
|
|
||
|
// Clean router.
|
||
|
func (r *DefaultRouter) Clean() {
|
||
|
r.r.mu.Lock()
|
||
|
defer r.r.mu.Unlock()
|
||
|
|
||
|
for key := range r.r.data {
|
||
|
delete(r.r.data, key)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
type defaultRoute struct {
|
||
|
functions []string
|
||
|
data map[frame.Tag]map[string]string
|
||
|
mu sync.RWMutex
|
||
|
}
|
||
|
|
||
|
func newRoute(functions []string) *defaultRoute {
|
||
|
return &defaultRoute{
|
||
|
functions: functions,
|
||
|
data: make(map[frame.Tag]map[string]string),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (r *defaultRoute) Add(connId string, name string, observeDataTags []frame.Tag) (err error) {
|
||
|
r.mu.Lock()
|
||
|
defer r.mu.Unlock()
|
||
|
|
||
|
ok := false
|
||
|
for _, v := range r.functions {
|
||
|
if v == name {
|
||
|
ok = true
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
if !ok {
|
||
|
return fmt.Errorf("SFN[%s] does not exist in config functions", name)
|
||
|
}
|
||
|
|
||
|
LOOP:
|
||
|
for _, conn := range r.data {
|
||
|
for connId, n := range conn {
|
||
|
if n == name {
|
||
|
err = herr.NewDuplicateNameError(connId, fmt.Errorf("SFN[%s] is already linked to another connection", name))
|
||
|
delete(conn, connId)
|
||
|
break LOOP
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for _, tag := range observeDataTags {
|
||
|
conn := r.data[tag]
|
||
|
if conn == nil {
|
||
|
conn = make(map[string]string)
|
||
|
r.data[tag] = conn
|
||
|
}
|
||
|
r.data[tag][connId] = name
|
||
|
}
|
||
|
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
func (r *defaultRoute) Remove(connId string) error {
|
||
|
r.mu.Lock()
|
||
|
defer r.mu.Unlock()
|
||
|
|
||
|
for _, conn := range r.data {
|
||
|
delete(conn, connId)
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (r *defaultRoute) GetForwardRoutes(tag frame.Tag) []string {
|
||
|
r.mu.RLock()
|
||
|
defer r.mu.RUnlock()
|
||
|
|
||
|
var keys []string
|
||
|
if conn := r.data[tag]; conn != nil {
|
||
|
for k := range conn {
|
||
|
keys = append(keys, k)
|
||
|
}
|
||
|
}
|
||
|
return keys
|
||
|
}
|