func (store *Internal) Get(k string) (string, error) {
	store.mu.RLock()
	defer store.mu.RUnlock()
	v, ok := store.entries[k]
	if ok && !v.expired() {
		return v.value, nil
	}
	return "", fmt.Errorf("No value in store for key: %v", k)
}
Get looks up an entry in the store.
package store
import (
	"fmt"
	"sync"
	"time"
	log "github.com/sirupsen/logrus"
)
type entry struct {
	value     string
	expiresOn time.Time
	noexpire  bool
}
func (e entry) expired() bool {
	if e.noexpire {
		return false
	}
	if time.Now().After(e.expiresOn) {
		return true
	}
	return false
}
type Internal struct {
	*Store
	entries    map[string]*entry
	ticker     *time.Ticker
	gcInterval time.Duration
	mu         *sync.RWMutex
}
func NewInternalStore() (*Internal, error) {
	return &Internal{
		Store: &Store{
			driver:     "internal",
			parameters: "",
		},
		entries:    make(map[string]*entry),
		ticker:     time.NewTicker(time.Second),
		gcInterval: 60 * time.Second,
		mu:         &sync.RWMutex{},
	}, nil
}
func (store *Internal) start() {
	go func() {
		for range store.ticker.C {
			store.expire()
		}
	}()
}
func (store *Internal) expire() {
	log.WithFields(log.Fields{"type": "store", "store": "internal"}).Infof("running garbage collector")
	count := 0
	for k, v := range store.entries {
		store.mu.Lock()
		if v.expired() {
			delete(store.entries, k)
			count++
		}
		store.mu.Unlock()
	}
	log.WithFields(log.Fields{"type": "store", "store": "internal"}).Infof("garbage collector deleted %d entries", count)
}
func (store *Internal) NumEntries() int {
	return len(store.entries)
}
func (store *Internal) Set(k string, v string, ttl time.Duration) error {
	expiresOn := time.Now().Add(ttl)
	noexpire := false
	if ttl == 0 {
		noexpire = true
	}
	store.mu.Lock()
	store.entries[k] = &entry{v, expiresOn, noexpire}
	store.mu.Unlock()
	return nil
}