Просмотр исходного кода

work around etcd not returning expiration

In case etcd fails to return expiration on keys that have a TTL,
calculate the expiration ourselves. It's a good way to bulletproof the code
Eugene Yakubovich 10 лет назад
Родитель
Сommit
8ae216e4cf
1 измененных файлов с 25 добавлено и 2 удалено
  1. 25 2
      subnet/registry.go

+ 25 - 2
subnet/registry.go

@@ -2,8 +2,10 @@ package subnet
 
 import (
 	"sync"
+	"time"
 
 	"github.com/coreos/rudder/Godeps/_workspace/src/github.com/coreos/go-etcd/etcd"
+	log "github.com/coreos/rudder/Godeps/_workspace/src/github.com/golang/glog"
 )
 
 type subnetRegistry interface {
@@ -42,11 +44,23 @@ func (esr *etcdSubnetRegistry) getSubnets() (*etcd.Response, error) {
 }
 
 func (esr *etcdSubnetRegistry) createSubnet(sn, data string, ttl uint64) (*etcd.Response, error) {
-	return esr.client().Create(esr.prefix+"/subnets/"+sn, data, ttl)
+	resp, err := esr.client().Create(esr.prefix+"/subnets/"+sn, data, ttl)
+	if err != nil {
+		return nil, err
+	}
+
+	ensureExpiration(resp, ttl)
+	return resp, nil
 }
 
 func (esr *etcdSubnetRegistry) updateSubnet(sn, data string, ttl uint64) (*etcd.Response, error) {
-	return esr.client().Set(esr.prefix+"/subnets/"+sn, data, ttl)
+	resp, err := esr.client().Set(esr.prefix+"/subnets/"+sn, data, ttl)
+	if err != nil {
+		return nil, err
+	}
+
+	ensureExpiration(resp, ttl)
+	return resp, nil
 }
 
 func (esr *etcdSubnetRegistry) watchSubnets(since uint64, stop chan bool) (*etcd.Response, error) {
@@ -83,3 +97,12 @@ func (esr *etcdSubnetRegistry) resetClient() {
 	defer esr.mux.Unlock()
 	esr.cli = etcd.NewClient([]string{esr.endpoint})
 }
+
+func ensureExpiration(resp *etcd.Response, ttl uint64) {
+	if resp.Node.Expiration == nil {
+		// should not be but calc it ourselves in this case
+		log.Info("Expiration field missing on etcd response, calculating locally")
+		exp := time.Now().Add(time.Duration(ttl) * time.Second)
+		resp.Node.Expiration = &exp
+	}
+}