1
0
Fork 0
mirror of https://github.com/alice-lg/birdwatcher.git synced 2025-03-09 00:00:05 +01:00

added caching to birdwatcher

This commit is contained in:
hellerve 2016-11-11 17:33:33 +01:00
parent 7c8ea17a06
commit 5bb95f264f
7 changed files with 67 additions and 38 deletions

View file

@ -3,37 +3,66 @@ package bird
import (
"os/exec"
"strings"
"time"
"sync"
)
var BirdCmd string
var Cache = struct{
sync.RWMutex
m map[string]Parsed
}{m: make(map[string]Parsed)}
func fromCache(key string) (Parsed, bool) {
Cache.RLock()
val, ok := Cache.m[key]
Cache.RUnlock()
return val, ok
}
func toCache(key string, val Parsed) {
val["ttl"] = time.Now().Add(5 * time.Minute)
Cache.Lock()
Cache.m[key] = val
Cache.Unlock()
}
func Run(args string) ([]byte, error) {
args = "show " + args
argsList := strings.Split(args, " ")
return exec.Command(BirdCmd, argsList...).Output()
}
func RunAndParse(cmd string, parser func([]byte) Parsed) Parsed {
func RunAndParse(cmd string, parser func([]byte) Parsed) (Parsed, bool) {
if val, ok := fromCache(cmd); ok {
return val, true
}
out, err := Run(cmd)
if err != nil {
// ignore errors for now
return Parsed{}
return Parsed{}, false
}
return parser(out)
parsed := parser(out)
toCache(cmd, parsed)
return parsed, false
}
func Status() Parsed {
func Status() (Parsed, bool) {
return RunAndParse("status", parseStatus)
}
func Protocols() Parsed {
func Protocols() (Parsed, bool) {
return RunAndParse("protocols all", parseProtocols)
}
func ProtocolsBgp() Parsed {
protocols := Protocols()["protocols"].([]string)
func ProtocolsBgp() (Parsed, bool) {
p, from_cache := Protocols()
protocols := p["protocols"].([]string)
bgpProto := Parsed{}
@ -44,49 +73,49 @@ func ProtocolsBgp() Parsed {
}
}
return Parsed{"protocols": bgpProto}
return Parsed{"protocols": bgpProto}, from_cache
}
func Symbols() Parsed {
func Symbols() (Parsed, bool) {
return RunAndParse("symbols", parseSymbols)
}
func RoutesProto(protocol string) Parsed {
func RoutesProto(protocol string) (Parsed, bool) {
return RunAndParse("route protocol "+protocol+" all",
parseRoutes)
}
func RoutesProtoCount(protocol string) Parsed {
func RoutesProtoCount(protocol string) (Parsed, bool) {
return RunAndParse("route protocol "+protocol+" count",
parseRoutesCount)
}
func RoutesExport(protocol string) Parsed {
func RoutesExport(protocol string) (Parsed, bool) {
return RunAndParse("route export "+protocol+" all",
parseRoutes)
}
func RoutesExportCount(protocol string) Parsed {
func RoutesExportCount(protocol string) (Parsed, bool) {
return RunAndParse("route export "+protocol+" count",
parseRoutesCount)
}
func RoutesTable(table string) Parsed {
func RoutesTable(table string) (Parsed, bool) {
return RunAndParse("route table "+table+" all",
parseRoutes)
}
func RoutesTableCount(table string) Parsed {
func RoutesTableCount(table string) (Parsed, bool) {
return RunAndParse("route table "+table+" count",
parseRoutesCount)
}
func RoutesLookupTable(net string, table string) Parsed {
func RoutesLookupTable(net string, table string) (Parsed, bool) {
return RunAndParse("route for "+net+" table "+table+" all",
parseRoutes)
}
func RoutesLookupProtocol(net string, protocol string) Parsed {
func RoutesLookupProtocol(net string, protocol string) (Parsed, bool) {
return RunAndParse("route for "+net+" protocol "+protocol+" all",
parseRoutes)
}

View file

@ -8,15 +8,14 @@ import (
"github.com/julienschmidt/httprouter"
)
func Endpoint(wrapped func(httprouter.Params) bird.Parsed) httprouter.Handle {
func Endpoint(wrapped func(httprouter.Params) (bird.Parsed, bool)) httprouter.Handle {
return func(w http.ResponseWriter,
r *http.Request,
ps httprouter.Params) {
res := make(map[string]interface{})
res["api"] = GetApiInfo()
ret := wrapped(ps)
ret, from_cache := wrapped(ps)
res["api"] = GetApiInfo(from_cache)
for k, v := range ret {
res[k] = v

View file

@ -5,10 +5,10 @@ import (
"github.com/julienschmidt/httprouter"
)
func Protocols(ps httprouter.Params) bird.Parsed {
func Protocols(ps httprouter.Params) (bird.Parsed, bool) {
return bird.Protocols()
}
func Bgp(ps httprouter.Params) bird.Parsed {
func Bgp(ps httprouter.Params) (bird.Parsed, bool) {
return bird.ProtocolsBgp()
}

View file

@ -5,26 +5,26 @@ import (
"github.com/julienschmidt/httprouter"
)
func ProtoRoutes(ps httprouter.Params) bird.Parsed {
func ProtoRoutes(ps httprouter.Params) (bird.Parsed, bool) {
return bird.RoutesProto(ps.ByName("protocol"))
}
func TableRoutes(ps httprouter.Params) bird.Parsed {
func TableRoutes(ps httprouter.Params) (bird.Parsed, bool) {
return bird.RoutesTable(ps.ByName("table"))
}
func ProtoCount(ps httprouter.Params) bird.Parsed {
func ProtoCount(ps httprouter.Params) (bird.Parsed, bool) {
return bird.RoutesProtoCount(ps.ByName("protocol"))
}
func TableCount(ps httprouter.Params) bird.Parsed {
func TableCount(ps httprouter.Params) (bird.Parsed, bool) {
return bird.RoutesTable(ps.ByName("table"))
}
func RouteNet(ps httprouter.Params) bird.Parsed {
func RouteNet(ps httprouter.Params) (bird.Parsed, bool) {
return bird.RoutesLookupTable(ps.ByName("net"), "master")
}
func RouteNetTable(ps httprouter.Params) bird.Parsed {
func RouteNetTable(ps httprouter.Params) (bird.Parsed, bool) {
return bird.RoutesLookupTable(ps.ByName("net"), ps.ByName("table"))
}

View file

@ -5,6 +5,6 @@ import (
"github.com/julienschmidt/httprouter"
)
func Status(ps httprouter.Params) bird.Parsed {
func Status(ps httprouter.Params) (bird.Parsed, bool) {
return bird.Status()
}

View file

@ -5,14 +5,16 @@ import (
"github.com/julienschmidt/httprouter"
)
func Symbols(ps httprouter.Params) bird.Parsed {
func Symbols(ps httprouter.Params) (bird.Parsed, bool) {
return bird.Symbols()
}
func SymbolTables(ps httprouter.Params) bird.Parsed {
return bird.Parsed{"symbols": bird.Symbols()["routing table"]}
func SymbolTables(ps httprouter.Params) (bird.Parsed, bool) {
val, from_cache := bird.Symbols()
return bird.Parsed{"symbols": val["routing table"]}, from_cache
}
func SymbolProtocols(ps httprouter.Params) bird.Parsed {
return bird.Parsed{"symbols": bird.Symbols()["protocols"]}
func SymbolProtocols(ps httprouter.Params) (bird.Parsed, bool) {
val, from_cache := bird.Symbols()
return bird.Parsed{"symbols": val["protocols"]}, from_cache
}

View file

@ -17,12 +17,11 @@ type APIInfo struct {
CacheStatus CacheStatus `json:"cache_status"`
}
func GetApiInfo() *APIInfo {
func GetApiInfo(from_cache bool) *APIInfo {
ai := &APIInfo{}
/* Dummy data until we implement caching */
ai.Version = "1.0"
ai.ResultFromCache = false
ai.ResultFromCache = from_cache
return ai
}