tailscale/portlist/poller.go

60 lines
1.2 KiB
Go
Raw Permalink Normal View History

// Copyright (c) 2020 Tailscale Inc & AUTHORS All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package portlist
import (
"time"
)
type Poller struct {
C chan List // new data when it arrives; closed when done
quitCh chan struct{} // close this to force exit
Err error // last returned error code, if any
prev List // most recent data
}
func NewPoller() (*Poller, error) {
p := &Poller{
C: make(chan List),
quitCh: make(chan struct{}),
}
// Do one initial poll synchronously, so the caller can react
// to any obvious errors.
p.prev, p.Err = GetList(nil)
return p, p.Err
}
func (p *Poller) Close() {
close(p.quitCh)
<-p.C
}
// Poll periodically. Run this in a goroutine if you want.
func (p *Poller) Run() error {
defer close(p.C)
tick := time.NewTicker(POLL_SECONDS * time.Second)
defer tick.Stop()
// Send out the pre-generated initial value
p.C <- p.prev
for {
select {
case <-tick.C:
pl, err := GetList(p.prev)
if err != nil {
p.Err = err
return p.Err
}
if !pl.SameInodes(p.prev) {
p.prev = pl
p.C <- pl
}
case <-p.quitCh:
return nil
}
}
}