Skip to content

Commit 5bea3f5

Browse files
committed
refactor
1 parent 9bfaffd commit 5bea3f5

1 file changed

Lines changed: 50 additions & 34 deletions

File tree

internal/zfs/zfs_evemt_watcher.go

Lines changed: 50 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -69,17 +69,19 @@ func parseZpoolEvents(reader io.Reader, startTime time.Time, onUpdate func()) {
6969
isTargetAction := false
7070
var eventTime time.Time
7171

72+
// Closure to handle the trigger logic cleanly (used for both empty lines and EOF)
73+
triggerIfValid := func() {
74+
if inHistoryEvent && isTargetAction && eventTime.After(startTime) {
75+
onUpdate()
76+
}
77+
}
78+
7279
for scanner.Scan() {
7380
line := strings.TrimSpace(scanner.Text())
7481

7582
// Empty line marks the end of an event block
7683
if line == "" {
77-
if inHistoryEvent && isTargetAction {
78-
// Only trigger if the event happened AFTER the watcher started
79-
if eventTime.After(startTime) {
80-
onUpdate()
81-
}
82-
}
84+
triggerIfValid()
8385

8486
// Reset block state for the next event
8587
inHistoryEvent = false
@@ -94,38 +96,52 @@ func parseZpoolEvents(reader io.Reader, startTime time.Time, onUpdate func()) {
9496
}
9597

9698
if inHistoryEvent {
97-
// 1. Check if the action is relevant
98-
if strings.HasPrefix(line, "history_str =") || strings.HasPrefix(line, "history_internal_name =") {
99-
if strings.Contains(line, "\"snapshot\"") || strings.Contains(line, "\"destroy\"") ||
100-
strings.Contains(line, "\"zfs snapshot ") || strings.Contains(line, "\"zfs destroy ") {
101-
isTargetAction = true
102-
}
103-
}
104-
105-
// 2. Extract and parse the event timestamp
106-
if strings.HasPrefix(line, "time = ") {
107-
parts := strings.Fields(line)
108-
if len(parts) >= 3 {
109-
secHex := strings.TrimPrefix(parts[2], "0x")
110-
sec, err := strconv.ParseInt(secHex, 16, 64)
111-
if err == nil {
112-
nsec := int64(0)
113-
if len(parts) >= 4 {
114-
nsecHex := strings.TrimPrefix(parts[3], "0x")
115-
nsec, _ = strconv.ParseInt(nsecHex, 16, 64)
116-
}
117-
eventTime = time.Unix(sec, nsec)
118-
}
119-
}
99+
if isTargetZfsAction(line) {
100+
isTargetAction = true
101+
} else if parsedTime, ok := parseEventTime(line); ok {
102+
eventTime = parsedTime
120103
}
121104
}
122-
} // End of scanner loop
105+
}
123106

124-
if inHistoryEvent && isTargetAction {
125-
if eventTime.After(startTime) {
126-
onUpdate()
127-
}
107+
// Catch the final event if the file didn't end with an empty line
108+
triggerIfValid()
109+
}
110+
111+
// isTargetZfsAction checks if the line indicates a snapshot creation or destruction
112+
func isTargetZfsAction(line string) bool {
113+
if !strings.HasPrefix(line, "history_str =") && !strings.HasPrefix(line, "history_internal_name =") {
114+
return false
128115
}
116+
117+
return strings.Contains(line, "\"snapshot\"") || strings.Contains(line, "\"destroy\"") ||
118+
strings.Contains(line, "\"zfs snapshot ") || strings.Contains(line, "\"zfs destroy ")
119+
}
120+
121+
// parseEventTime extracts and parses the hex timestamp from a ZFS event time line
122+
func parseEventTime(line string) (time.Time, bool) {
123+
if !strings.HasPrefix(line, "time = ") {
124+
return time.Time{}, false
125+
}
126+
127+
parts := strings.Fields(line)
128+
if len(parts) < 3 {
129+
return time.Time{}, false
130+
}
131+
132+
secHex := strings.TrimPrefix(parts[2], "0x")
133+
sec, err := strconv.ParseInt(secHex, 16, 64)
134+
if err != nil {
135+
return time.Time{}, false
136+
}
137+
138+
nsec := int64(0)
139+
if len(parts) >= 4 {
140+
nsecHex := strings.TrimPrefix(parts[3], "0x")
141+
nsec, _ = strconv.ParseInt(nsecHex, 16, 64)
142+
}
143+
144+
return time.Unix(sec, nsec), true
129145
}
130146

131147
func AddZpoolEventWatcherActor(g *run.Group, ctx context.Context) {

0 commit comments

Comments
 (0)