-
Notifications
You must be signed in to change notification settings - Fork 1
/
watch.go
71 lines (60 loc) · 1.48 KB
/
watch.go
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
//go:build windows
// +build windows
package winproc
import (
"context"
"time"
)
// Watch polls the process tree on an interval until an error is encountered
// or the context is cancelled. It sends differences in the process list on
// the returned channel.
//
// This function is experimental and may be changed in future revisions.
func Watch(ctx context.Context, interval time.Duration, chanSize int, options ...CollectionOption) <-chan ChangeSet {
ch := make(chan ChangeSet, chanSize)
go func() {
defer close(ch)
ticker := time.NewTicker(interval)
defer ticker.Stop()
known := make(map[UniqueID]Process)
for {
select {
case <-ctx.Done():
ch <- ChangeSet{Err: ctx.Err(), Time: time.Now()}
return
case <-ticker.C:
list, err := List(options...)
if err != nil {
ch <- ChangeSet{Err: err, Time: time.Now()}
return
}
var (
current = make(map[UniqueID]struct{})
changes []Change
)
for i := range list {
id := list[i].UniqueID()
current[id] = struct{}{}
if _, exists := known[id]; exists {
continue
}
known[id] = list[i]
changes = append(changes, Change{Process: list[i]})
}
for id := range known {
if _, found := current[id]; !found {
changes = append(changes, Change{Process: known[id], Removed: true})
delete(known, id)
}
}
if len(changes) > 0 {
ch <- ChangeSet{
Changes: changes,
Time: time.Now(),
}
}
}
}
}()
return ch
}