portlist: document, clean up, fix an open fd spike, optimize a bit

I noticed portlist when looking at some profiles and hadn't looked at
the code much before. This is a first pass over it. It allocates a
fair bit. More love remains, but this does a bit:

name       old time/op    new time/op    delta
GetList-8    9.92ms ± 8%    9.64ms ±12%     ~     (p=0.247 n=10+10)

name       old alloc/op   new alloc/op   delta
GetList-8     931kB ± 0%     869kB ± 0%   -6.70%  (p=0.000 n=10+10)

name       old allocs/op  new allocs/op  delta
GetList-8     4.59k ± 0%     3.69k ± 1%  -19.71%  (p=0.000 n=10+10)

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
Brad Fitzpatrick
2020-03-13 20:53:58 -07:00
committed by Brad Fitzpatrick
parent 6c3820e8c4
commit 120273d7f6
9 changed files with 181 additions and 94 deletions

View File

@@ -5,6 +5,7 @@
package ipn
import (
"context"
"errors"
"fmt"
"log"
@@ -27,6 +28,8 @@ import (
// plane and the local network stack, wiring up NetworkMap updates
// from the cloud to the local WireGuard engine.
type LocalBackend struct {
ctx context.Context // valid until Close
ctxCancel context.CancelFunc // closes ctx
logf logger.Logf
e wgengine.Engine
store StateStore
@@ -66,12 +69,15 @@ func NewLocalBackend(logf logger.Logf, logid string, store StateStore, e wgengin
// Default filter blocks everything, until Start() is called.
e.SetFilter(filter.NewAllowNone())
ctx, cancel := context.WithCancel(context.Background())
portpoll, err := portlist.NewPoller()
if err != nil {
logf("skipping portlist: %s\n", err)
}
b := &LocalBackend{
ctx: ctx,
ctxCancel: cancel,
logf: logf,
e: e,
store: store,
@@ -84,7 +90,7 @@ func NewLocalBackend(logf logger.Logf, logid string, store StateStore, e wgengin
e.SetNetInfoCallback(b.SetNetInfo)
if b.portpoll != nil {
go b.portpoll.Run()
go b.portpoll.Run(ctx)
go b.runPoller()
}
@@ -92,9 +98,7 @@ func NewLocalBackend(logf logger.Logf, logid string, store StateStore, e wgengin
}
func (b *LocalBackend) Shutdown() {
if b.portpoll != nil {
b.portpoll.Close()
}
b.ctxCancel()
b.c.Shutdown()
b.e.Close()
b.e.Wait()
@@ -313,9 +317,9 @@ func (b *LocalBackend) updateFilter(netMap *controlclient.NetworkMap) {
func (b *LocalBackend) runPoller() {
for {
ports := <-b.portpoll.C
if ports == nil {
break
ports, ok := <-b.portpoll.C
if !ok {
return
}
sl := []tailcfg.Service{}
for _, p := range ports {