func (e *Election) WithMastership(ctx context.Context) (context.Context, error) {
	cctx, cancel := context.WithCancel(ctx)
	etcdRev := e.election.Rev()  
	if etcdRev == 0 {
		cancel()
		return cctx, nil
	}
	ch := e.election.Observe(cctx)
	select {
	case <-ctx.Done():
		cancel()
		return nil, ctx.Err()
	case rsp, ok := <-ch:
		kv := rsp.Kvs[0]
		if !ok || kv.CreateRevision != etcdRev || string(kv.Value) == resignID {
			cancel()
			return cctx, nil
		}
	}
	go func() {
		defer func() {
			cancel()
			glog.Infof("%s: canceled mastership context", e.resourceID)
		}()
		for rsp := range ch {
			kv := rsp.Kvs[0]
			if kv.CreateRevision != etcdRev {
				conquerorID := string(kv.Value)
				glog.Warningf("%s: mastership overtaken by %s", e.resourceID, conquerorID)
				break
			} else if string(kv.Value) == resignID {
				glog.Infof("%s: canceling context due to resignation", e.resourceID)
				break
			}
		}
	}()
	return cctx, nil
}
WithMastership returns a "mastership context" which remains active until the
instance stops being the master, or the passed in context is canceled.
package etcd
import (
	"context"
	"fmt"
	"strings"
	"github.com/golang/glog"
	"github.com/google/trillian/util/election2"
	clientv3 "go.etcd.io/etcd/client/v3"
	"go.etcd.io/etcd/client/v3/concurrency"
)
const resignID = "<resign>"
type Election struct {
	resourceID string
	instanceID string
	lockFile   string
	client   *clientv3.Client
	session  *concurrency.Session
	election *concurrency.Election
}
func (e *Election) Await(ctx context.Context) error {
	return e.election.Campaign(ctx, e.instanceID)
}