func GenerateStringHandler(dconfigKey string, setter SetterString, getter GetterString) Handler {
	handlerFunc := func(newConfig interface{}) {
		oldValue := getter()
		newValue, ok := newConfig.(string)
		if !ok {
			log.WithField("dconfigKey", dconfigKey).Error("Cannot get key from dconfig; just using the old value.")
		} else if oldValue == newValue {
			log.Info("oldValue is equal to newValue, do not need to update")
		} else {
			setter(string(newValue))
		}
		log.WithFields(log.Fields{fmt.Sprintf("old%s", dconfigKey): oldValue, fmt.Sprintf("new%s", dconfigKey): getter()}).
			Info("new value vs old value for the dconfig key")
	}
	return handlerFunc
}
GenerateStringHandler return a dconfig Handler for the dconfigKey
package dconfigclient
import (
	"fmt"
	"regexp"
	log "github.com/sirupsen/logrus"
)
type SetterInt func(value int32)
type GetterInt func() int
type SetterString func(value string)
type GetterString func() string
func GenerateIntHandler(dconfigKey string, setter SetterInt, getter GetterInt) Handler {
	handlerFunc := func(newConfig interface{}) {
		oldValue := getter()
		newValue, ok := newConfig.(int)
		if !ok {
			log.WithField("dconfigKey", dconfigKey).Error("Cannot get key from dconfig; just using the old value.")
		} else if oldValue == newValue {
			log.Info("oldValue is equal to newValue, do not need to update")
		} else {
			setter(int32(newValue))
		}
		log.WithFields(log.Fields{fmt.Sprintf("old%s", dconfigKey): oldValue, fmt.Sprintf("new%s", dconfigKey): getter()}).
			Info("new value vs old value for the dconfig key")
	}
	return handlerFunc
}
func GenerateIntMaxMinVerifier(dconfigKey string, minV int, maxV int) Verifier {
	verifierFunc := func(_ interface{}, newV interface{}) bool {
		newValue, okNew := newV.(int)
		if !okNew {
			log.WithFields(log.Fields{"dconfigKey": dconfigKey, "newValue": fmt.Sprintf("%v", newV)}).Error("type-assertion to int failed for the dconfig key")
			return false
		}
		if newValue < minV && newValue > maxV {
			log.WithFields(log.Fields{"dconfigKey": dconfigKey, "newValue": fmt.Sprintf("%v", newValue), "min": fmt.Sprintf("%v", minV), "max": fmt.Sprintf("%v", maxV)}).Error("verify for the dconfigKey failed; new value doesn't fall between min and max")
			return false
		}
		return true
	}
	return verifierFunc
}
func GenerateStringRegexpVerifier(dconfigKey string, r *regexp.Regexp) Verifier {
	verifierFunc := func(_ interface{}, newV interface{}) bool {
		newValue, okNew := newV.(string)
		if !okNew {
			log.WithFields(log.Fields{"dconfigKey": dconfigKey, "newValue": fmt.Sprintf("%v", newV)}).Error("type-assertion to string failed for the dconfig key")
			return false
		}
		if !r.MatchString(newValue) {
			log.WithFields(log.Fields{"dconfigKey": dconfigKey, "newValue": fmt.Sprintf("%v", newValue), "regexp": r.String()}).Error("verify for the dconfigKey failed; new value doesn't match regular expression")
			return false
		}
		return true
	}
	return verifierFunc
}