package router import ( "sync" "time" ) type RoutingEntry struct { tag string err error expire time.Time } func (v *RoutingEntry) Extend() { v.expire = time.Now().Add(time.Hour) } func (v *RoutingEntry) Expired() bool { return v.expire.Before(time.Now()) } type RoutingTable struct { sync.RWMutex table map[string]*RoutingEntry } func NewRoutingTable() *RoutingTable { return &RoutingTable{ table: make(map[string]*RoutingEntry), } } func (v *RoutingTable) Cleanup() { v.Lock() defer v.Unlock() for key, value := range v.table { if value.Expired() { delete(v.table, key) } } } func (v *RoutingTable) Set(destination string, tag string, err error) { v.Lock() defer v.Unlock() entry := &RoutingEntry{ tag: tag, err: err, } entry.Extend() v.table[destination] = entry if len(v.table) > 1000 { go v.Cleanup() } } func (v *RoutingTable) Get(destination string) (bool, string, error) { v.RLock() defer v.RUnlock() entry, found := v.table[destination] if !found { return false, "", nil } entry.Extend() return true, entry.tag, entry.err }