OSDN Git Service

rename
[bytom/vapor.git] / toolbar / precog / monitor / stats.go
1 package monitor
2
3 import (
4         "database/sql"
5         "fmt"
6         "time"
7
8         "github.com/jinzhu/gorm"
9         log "github.com/sirupsen/logrus"
10
11         "github.com/vapor/crypto/ed25519/chainkd"
12         "github.com/vapor/netsync/peers"
13         "github.com/vapor/toolbar/precog/common"
14         "github.com/vapor/toolbar/precog/config"
15         "github.com/vapor/toolbar/precog/database/orm"
16 )
17
18 // TODO: get lantency
19 // TODO: get best_height
20 // TODO: decide check_height("best best_height" - "confirmations")
21 // TODO: get blockhash by check_height, get latency
22 // TODO: update lantency, active_time and status
23
24 // create or update: https://github.com/jinzhu/gorm/issues/1307
25 func (m *monitor) upSertNode(node *config.Node) error {
26         if node.XPub != nil {
27                 node.PublicKey = fmt.Sprintf("%v", node.XPub.PublicKey().String())
28         }
29
30         ormNode := &orm.Node{PublicKey: node.PublicKey}
31         if err := m.db.Where(&orm.Node{PublicKey: node.PublicKey}).First(ormNode).Error; err != nil && err != gorm.ErrRecordNotFound {
32                 return err
33         }
34
35         if node.Alias != "" {
36                 ormNode.Alias = node.Alias
37         }
38         if node.XPub != nil {
39                 ormNode.Xpub = node.XPub.String()
40         }
41         ormNode.Host = node.Host
42         ormNode.Port = node.Port
43         return m.db.Where(&orm.Node{PublicKey: ormNode.PublicKey}).
44                 Assign(&orm.Node{
45                         Xpub:  ormNode.Xpub,
46                         Alias: ormNode.Alias,
47                         Host:  ormNode.Host,
48                         Port:  ormNode.Port,
49                 }).FirstOrCreate(ormNode).Error
50 }
51
52 func (m *monitor) processPeerInfos(peerInfos []*peers.PeerInfo) error {
53         for _, peerInfo := range peerInfos {
54                 dbTx := m.db.Begin()
55                 if err := m.processPeerInfo(dbTx, peerInfo); err != nil {
56                         log.Error(err)
57                         dbTx.Rollback()
58                 } else {
59                         dbTx.Commit()
60                 }
61         }
62
63         return nil
64 }
65
66 func (m *monitor) processPeerInfo(dbTx *gorm.DB, peerInfo *peers.PeerInfo) error {
67         xPub := &chainkd.XPub{}
68         if err := xPub.UnmarshalText([]byte(peerInfo.ID)); err != nil {
69                 return err
70         }
71
72         ormNode := &orm.Node{}
73         if err := dbTx.Model(&orm.Node{}).Where(&orm.Node{PublicKey: xPub.PublicKey().String()}).First(ormNode).Error; err != nil {
74                 return err
75         }
76
77         log.Debugf("peerInfo.Ping: %v", peerInfo.Ping)
78         ping, err := time.ParseDuration(peerInfo.Ping)
79         if err != nil {
80                 log.Debugf("Parse ping time err: %v", err)
81         }
82
83         // TODO: preload?
84         ormNodeLiveness := &orm.NodeLiveness{
85                 NodeID:        ormNode.ID,
86                 BestHeight:    ormNode.BestHeight,
87                 AvgLantencyMS: sql.NullInt64{Int64: ping.Nanoseconds() / 1000, Valid: true},
88                 // PingTimes     uint64
89                 // PongTimes     uint64
90         }
91         if err := dbTx.Model(&orm.NodeLiveness{}).Where("node_id = ? AND status != ?", ormNode.ID, common.NodeOfflineStatus).
92                 UpdateColumn(&orm.NodeLiveness{
93                         BestHeight:    ormNodeLiveness.BestHeight,
94                         AvgLantencyMS: ormNodeLiveness.AvgLantencyMS,
95                 }).FirstOrCreate(ormNodeLiveness).Error; err != nil {
96                 return err
97         }
98
99         if err := dbTx.Model(&orm.Node{}).Where(&orm.Node{PublicKey: xPub.PublicKey().String()}).
100                 UpdateColumn(&orm.Node{
101                         Alias:      peerInfo.Moniker,
102                         Xpub:       peerInfo.ID,
103                         BestHeight: peerInfo.Height,
104                         // LatestDailyUptimeMinutes uint64
105                 }).First(ormNode).Error; err != nil {
106                 return err
107         }
108
109         return nil
110 }