func (j *janitorRunner) getLock(worker string) (*redsync.Mutex, error) {
	mu, err := redsync.NewMutexWithPool("redutil:lock:"+worker, []*redis.Pool{j.pool})
	if err != nil {
		return nil, err
	}
	return mu, mu.Lock()
}
Creates a mutex and attempts to acquire a redlock to dispose of the worker.
package worker
import (
	"math/rand"
	"sync"
	"time"
	"github.com/benbjohnson/clock"
	"github.com/garyburd/redigo/redis"
	"github.com/hjr265/redsync.go/redsync"
	"github.com/mixer/redutil/heartbeat"
	"github.com/mixer/redutil/queue"
)
type Janitor interface {
	OnPreConcat(cnx redis.Conn, worker string) error
	OnPostConcat(cnx redis.Conn, worker string) error
}
type nilJanitor struct{}
var _ Janitor = nilJanitor{}
func (n nilJanitor) OnPreConcat(cnx redis.Conn, worker string) error  { return nil }
func (n nilJanitor) OnPostConcat(cnx redis.Conn, worker string) error { return nil }
type janitorRunner struct {
	pool *redis.Pool
	availableTasks queue.Queue
	detector heartbeat.Detector
	janitor  Janitor
	interval time.Duration
	clock clock.Clock
	errs   chan error
	closer chan struct{}
}
func newJanitorRunner(pool *redis.Pool, detector heartbeat.Detector, janitor Janitor,
	availableTasks queue.Queue) *janitorRunner {
	return &janitorRunner{
		pool:           pool,
		availableTasks: availableTasks,
		detector:       detector,
		janitor:        janitor,
		clock:          clock.New(),
		interval:       defaultMonitorInterval,
		errs:           make(chan error),
		closer:         make(chan struct{}),
	}
}
func (j *janitorRunner) watchDead() {
	defer close(j.errs)
	select {
	case <-j.closer:
		return
	case <-j.clock.After(time.Duration(float64(j.interval) * rand.Float64())):
	}
	ticker := j.clock.Ticker(j.interval)
	defer ticker.Stop()
	for {
		select {
		case <-j.closer:
			return
		case <-ticker.C:
			j.runCleaning()
		}
	}
}
func (j *janitorRunner) runCleaning() {
	dead, err := j.detector.Detect()
	if err != nil {
		j.errs <- err
		return
	}
	var wg sync.WaitGroup
	wg.Add(len(dead))
	for _, worker := range dead {
		go func(worker string) {
			defer wg.Done()
			err := j.handleDeath(worker)
			if err != nil && err != redsync.ErrFailed {
				j.errs <- err
			}
		}(worker)
	}
	wg.Wait()
}