79 lines
1.7 KiB
Go
79 lines
1.7 KiB
Go
package web
|
|
|
|
import (
|
|
"openreplay/backend/pkg/messages"
|
|
)
|
|
|
|
const CrashWindow = 2 * 1000
|
|
const CrashThreshold = 70
|
|
|
|
type AppCrashDetector struct {
|
|
dropTimestamp uint64
|
|
dropMessageID uint64
|
|
lastIssueTimestamp uint64
|
|
}
|
|
|
|
func NewAppCrashDetector() *AppCrashDetector {
|
|
return &AppCrashDetector{}
|
|
}
|
|
|
|
func (h *AppCrashDetector) reset() {
|
|
h.dropTimestamp = 0
|
|
h.lastIssueTimestamp = 0
|
|
}
|
|
|
|
func (h *AppCrashDetector) updateLastIssueTimestamp(msgTimestamp uint64) {
|
|
if msgTimestamp > h.lastIssueTimestamp {
|
|
h.lastIssueTimestamp = msgTimestamp
|
|
}
|
|
}
|
|
|
|
func (h *AppCrashDetector) build() messages.Message {
|
|
if h.dropTimestamp == 0 || h.lastIssueTimestamp == 0 {
|
|
// Nothing to build
|
|
return nil
|
|
}
|
|
|
|
// Calculate timestamp difference
|
|
var diff uint64
|
|
if h.lastIssueTimestamp > h.dropTimestamp {
|
|
diff = h.lastIssueTimestamp - h.dropTimestamp
|
|
} else {
|
|
diff = h.dropTimestamp - h.lastIssueTimestamp
|
|
}
|
|
|
|
// Check possible app crash
|
|
if diff < CrashWindow {
|
|
msg := &messages.IssueEvent{
|
|
MessageID: h.dropMessageID,
|
|
Timestamp: h.dropTimestamp,
|
|
Type: "app_crash",
|
|
}
|
|
h.reset()
|
|
return msg
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (h *AppCrashDetector) Handle(message messages.Message, timestamp uint64) messages.Message {
|
|
switch msg := message.(type) {
|
|
case *messages.UnbindNodes:
|
|
if msg.TotalRemovedPercent < CrashThreshold {
|
|
// Not enough nodes removed
|
|
return nil
|
|
}
|
|
h.dropTimestamp = timestamp
|
|
h.dropMessageID = msg.MsgID()
|
|
case *messages.JSException:
|
|
h.updateLastIssueTimestamp(msg.Timestamp)
|
|
case *messages.NetworkRequest:
|
|
if msg.Status >= 400 {
|
|
h.updateLastIssueTimestamp(msg.Timestamp)
|
|
}
|
|
}
|
|
return h.build()
|
|
}
|
|
|
|
func (h *AppCrashDetector) Build() messages.Message {
|
|
return h.build()
|
|
}
|