func (w *worker) isStable() bool {
	w.touchMu.Lock()
	defer w.touchMu.Unlock()
	return time.Since(w.lastTouchTime) >= time.Second*2
}
isStable returns true if the worker hasn't been touched in 2 seconds or
longer, and returns false otherwise. This was inteded to be used to denote
some sort of "readiness", as the worker will be constantly creating
port-forwards when starting up, draining the initial queue created by
the proxier.
package proxier
import (
	"context"
	"fmt"
	"io/ioutil"
	"net"
	"net/http"
	"os"
	"os/exec"
	"runtime"
	"sync"
	"time"
	"github.com/getoutreach/localizer/pkg/hostsfile"
	"github.com/metal-stack/go-ipam"
	"github.com/pkg/errors"
	"github.com/sirupsen/logrus"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/rest"
	"k8s.io/client-go/tools/portforward"
	"k8s.io/client-go/transport/spdy"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
type worker struct {
	k    kubernetes.Interface
	rest *rest.Config
	log  logrus.FieldLogger
	ippool ipam.Ipamer
	ipCidr string
	dns    *hostsfile.File
	reqChan  chan PortForwardRequest
	doneChan chan<- struct{}
	portForwards map[string]*PortForwardConnection
	lastTouchTime time.Time
	touchMu       sync.Mutex
}
func NewPortForwarder(ctx context.Context, k kubernetes.Interface,
	r *rest.Config, log logrus.FieldLogger, opts *ProxyOpts) (chan<- PortForwardRequest, <-chan struct{}, *worker, error) {  
	ipamInstance := ipam.New()
	_, cidr, err := net.ParseCIDR(opts.IPCidr)
	if err != nil {
		return nil, nil, nil, errors.Wrap(err, "failed to parse provided cidr")
	}
	prefix, err := ipamInstance.NewPrefix(opts.IPCidr)
	if err != nil {
		return nil, nil, nil, errors.Wrap(err, "failed to create ip pool")
	}
	defaultIP := "127.0.0.1"
	if cidr.Contains(net.ParseIP(defaultIP)) {
		_, err = ipamInstance.AcquireSpecificIP(prefix.Cidr, defaultIP)
		if err != nil {
			return nil, nil, nil, errors.Wrap(err, "failed to create ip pool")
		}
	}
	hosts, err := hostsfile.New("", "")
	if err != nil {
		return nil, nil, nil, errors.Wrap(err, "failed to open up hosts file for r/w")
	}
	doneChan := make(chan struct{})
	reqChan := make(chan PortForwardRequest, 1024)
	w := &worker{
		k:             k,
		rest:          r,
		log:           log,
		ippool:        ipamInstance,
		ipCidr:        prefix.Cidr,
		dns:           hosts,
		reqChan:       reqChan,
		doneChan:      doneChan,
		portForwards:  make(map[string]*PortForwardConnection),
		lastTouchTime: time.Now(),
	}
	go w.Start(ctx)
	return reqChan, doneChan, w, nil
}
func (w *worker) Start(ctx context.Context) {
	for {
		select {
		case <-ctx.Done():
			for info := range w.portForwards {
				err := w.DeletePortForward(ctx, &DeletePortForwardRequest{
					Service: w.portForwards[info].Service,
				})
				if err != nil {
					w.log.WithError(err).Warn("failed to clean up port-forward")
				}
			}
			close(w.doneChan)
			return
		case req := <-w.reqChan:
			var serv ServiceInfo
			var err error
			if req.CreatePortForwardRequest != nil {
				err = w.CreatePortForward(ctx, req.CreatePortForwardRequest)
				serv = req.CreatePortForwardRequest.Service
			} else if req.DeletePortForwardRequest != nil {
				err = w.DeletePortForward(ctx, req.DeletePortForwardRequest)
				serv = req.DeletePortForwardRequest.Service
			}
			log := w.log.WithField("service", serv.Key())
			if err != nil {
				log.WithError(err).Errorf("encountered an error: %v", err)
			}
		}
	}
}
func (w *worker) touch() {
	w.touchMu.Lock()
	defer w.touchMu.Unlock()
	w.lastTouchTime = time.Now()
}