Do some magic reflection stuff

This commit is contained in:
Julian Kornberger 2016-03-12 00:59:36 +01:00
parent 14ad523b7f
commit 9923e0a4f2
3 changed files with 33 additions and 33 deletions

32
main.go
View File

@ -1,7 +1,6 @@
package main
import (
"encoding/json"
"flag"
"log"
"net"
@ -50,29 +49,16 @@ func main() {
}
if config.Respondd.Enable {
multiCollector = respond.NewMultiCollector(collectInterval, func(coll *respond.Collector, res *respond.Response) {
switch coll.CollectType {
case "neighbours":
result := &data.NeighbourStruct{}
if json.Unmarshal(res.Raw, result) == nil {
node := nodes.Get(result.NodeId)
node.Neighbours = result
}
case "nodeinfo":
result := &data.NodeInfo{}
if json.Unmarshal(res.Raw, result) == nil {
node := nodes.Get(result.NodeId)
node.Nodeinfo = result
}
case "statistics":
result := &data.StatisticsStruct{}
if json.Unmarshal(res.Raw, result) == nil {
node := nodes.Get(result.NodeId)
node.Statistics = result
}
multiCollector = respond.NewMultiCollector(collectInterval, func(addr net.UDPAddr, msg interface{}) {
switch msg := msg.(type) {
case *data.NodeInfo:
nodes.Get(msg.NodeId).Nodeinfo = msg
case *data.NeighbourStruct:
nodes.Get(msg.NodeId).Neighbours = msg
case *data.StatisticsStruct:
nodes.Get(msg.NodeId).Statistics = msg
default:
log.Println("unknown CollectType:", coll.CollectType)
log.Println("unknown message:", msg)
}
})
}

View File

@ -1,8 +1,10 @@
package respond
import (
"encoding/json"
"log"
"net"
"reflect"
"time"
)
@ -11,17 +13,18 @@ type Collector struct {
CollectType string
connection *net.UDPConn // UDP socket
queue chan *Response // received responses
parse func(coll *Collector, res *Response)
onReceive OnReceive
msgType reflect.Type
// Ticker and stopper
ticker *time.Ticker
stop chan interface{}
}
type ParseFunc func(coll *Collector, res *Response)
type OnReceive func(net.UDPAddr, interface{})
//NewCollector creates a Collector struct
func NewCollector(CollectType string, interval time.Duration, parseFunc ParseFunc) *Collector {
func NewCollector(CollectType string, interval time.Duration, msgStruct interface{}, onReceive OnReceive) *Collector {
// Parse address
addr, err := net.ResolveUDPAddr("udp", "[::]:0")
if err != nil {
@ -39,9 +42,10 @@ func NewCollector(CollectType string, interval time.Duration, parseFunc ParseFun
CollectType: CollectType,
connection: conn,
queue: make(chan *Response, 400),
parse: parseFunc,
ticker: time.NewTicker(interval),
stop: make(chan interface{}, 1),
msgType: reflect.TypeOf(msgStruct),
onReceive: onReceive,
}
go collector.receiver()
@ -91,7 +95,14 @@ func (coll *Collector) sender() {
func (coll *Collector) parser() {
for obj := range coll.queue {
coll.parse(coll, obj)
// create new struct instance
data := reflect.New(coll.msgType).Interface()
if err := json.Unmarshal(obj.Raw, data); err == nil {
coll.onReceive(obj.Address, data)
} else {
log.Println("unable to decode response from", obj.Address.String(), err)
}
}
}

View File

@ -1,6 +1,9 @@
package respond
import "time"
import (
"github.com/ffdo/node-informant/gluon-collector/data"
"time"
)
//MultiCollector struct
type MultiCollector struct {
@ -8,12 +11,12 @@ type MultiCollector struct {
}
//NewMultiCollector create a list of collectors
func NewMultiCollector(interval time.Duration, parseFunc ParseFunc) *MultiCollector {
func NewMultiCollector(interval time.Duration, onReceive OnReceive) *MultiCollector {
return &MultiCollector{
collectors: []*Collector{
NewCollector("statistics", interval, parseFunc),
NewCollector("nodeinfo", interval, parseFunc),
NewCollector("neighbours", interval, parseFunc),
NewCollector("statistics", interval, data.StatisticsStruct{}, onReceive),
NewCollector("nodeinfo", interval, data.NodeInfo{}, onReceive),
NewCollector("neighbours", interval, data.NeighbourStruct{}, onReceive),
},
}
}