-
Notifications
You must be signed in to change notification settings - Fork 218
Expand file tree
/
Copy pathtxnz.go
More file actions
137 lines (122 loc) · 3.61 KB
/
txnz.go
File metadata and controls
137 lines (122 loc) · 3.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
/*
* Radon
*
* Copyright 2018 The Radon Authors.
* Code is licensed under the GPLv3.
*
* This code was derived from https://github.com/youtube/vitess.
*/
package backend
import (
"sort"
"sync"
"time"
)
// TxnDetail is a simple wrapper for Query
type TxnDetail struct {
txnID uint64
txn Transaction
start time.Time
}
// NewTxnDetail creates a new TxnDetail
func NewTxnDetail(txn Transaction) *TxnDetail {
return &TxnDetail{txnID: txn.TxID(), txn: txn, start: time.Now()}
}
// Txnz holds a thread safe list of TxnDetails
type Txnz struct {
mu sync.RWMutex
txnDetails map[uint64]*TxnDetail
}
// NewTxnz creates a new Txnz
func NewTxnz() *Txnz {
return &Txnz{txnDetails: make(map[uint64]*TxnDetail)}
}
// Add adds a TxnDetail to Txnz
func (tz *Txnz) Add(td *TxnDetail) {
tz.mu.Lock()
defer tz.mu.Unlock()
tz.txnDetails[td.txnID] = td
}
// Remove removes a TxnDetail from Txnz
func (tz *Txnz) Remove(td *TxnDetail) {
tz.mu.Lock()
defer tz.mu.Unlock()
delete(tz.txnDetails, td.txnID)
}
// TxnDetailzRow is used for rendering TxnDetail in a template
type TxnDetailzRow struct {
Start time.Time
Duration time.Duration
TxnID uint64
XAID string
Query string
State string
XaState string
Color string
}
type byTxStartTime []TxnDetailzRow
func (a byTxStartTime) Len() int { return len(a) }
func (a byTxStartTime) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a byTxStartTime) Less(i, j int) bool { return a[i].Start.Before(a[j].Start) }
var (
txnStates = map[int32]string{
int32(txnStateLive): "txnStateLive",
int32(txnStateBeginning): "txnStateBeginning",
int32(txnStateExecutingTwoPC): "txnStateExecutingTwoPC",
int32(txnStateExecutingNormal): "txnStateExecutingNormal",
int32(txnStateRollbacking): "txnStateRollbacking",
int32(txnStateCommitting): "txnStateCommitting",
int32(txnStateFinshing): "txnStateFinshing",
int32(txnStateAborting): "txnStateAborting",
int32(txnStateRecovering): "txnStateRecovering",
}
xaStates = map[int32]string{
int32(txnXAStateNone): "txnXAStateNone",
int32(txnXAStateStart): "txnXAStateStart",
int32(txnXAStateStartFinished): "txnXAStateStartFinished",
int32(txnXAStateEnd): "txnXAStateEnd",
int32(txnXAStateEndFinished): "txnXAStateEndFinished",
int32(txnXAStatePrepare): "txnXAStatePrepare",
int32(txnXAStatePrepareFinished): "txnXAStatePrepareFinished",
int32(txnXAStateCommit): "txnXAStateCommit",
int32(txnXAStateCommitFinished): "txnXAStateCommitFinished",
int32(txnXAStateRollback): "txnXAStateRollback",
int32(txnXAStateRollbackFinished): "txnXAStateRollbackFinished",
int32(txnXAStateRecover): "txnXAStateRecover",
int32(txnXAStateRecoverFinished): "txnXAStateRecoverFinished",
}
)
// GetTxnzRows returns a list of TxnDetailzRow sorted by start time
func (tz *Txnz) GetTxnzRows() []TxnDetailzRow {
tz.mu.RLock()
rows := []TxnDetailzRow{}
for _, td := range tz.txnDetails {
state := "UNKNOW"
if s, ok := txnStates[td.txn.State()]; ok {
state = s
}
xaState := "NONE"
if s, ok := xaStates[td.txn.XaState()]; ok {
xaState = s
}
row := TxnDetailzRow{
Start: td.start,
Duration: time.Since(td.start),
TxnID: td.txnID,
XAID: td.txn.XID(),
State: state,
XaState: xaState,
}
if row.Duration < 10*time.Millisecond {
row.Color = "low"
} else if row.Duration < 100*time.Millisecond {
row.Color = "medium"
} else {
row.Color = "high"
}
rows = append(rows, row)
}
tz.mu.RUnlock()
sort.Sort(byTxStartTime(rows))
return rows
}