diff options
author | Raúl Benencia <raul@thousandeyes.com> | 2018-04-13 16:30:31 -0700 |
---|---|---|
committer | Raúl Benencia <raul@thousandeyes.com> | 2018-05-11 15:02:34 -0700 |
commit | 77c172b823b64ebface655681ab0749b9d2f7081 (patch) | |
tree | 09c13e626eb95ae1d33e76ed683172eab1ab6c96 /internal/server/server.go |
First public commit
Diffstat (limited to 'internal/server/server.go')
-rw-r--r-- | internal/server/server.go | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/internal/server/server.go b/internal/server/server.go new file mode 100644 index 0000000..1bc7e88 --- /dev/null +++ b/internal/server/server.go @@ -0,0 +1,123 @@ +// Copyright 2018 ThousandEyes Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package server + +import ( + "sync" + "time" + + "github.com/thousandeyes/shoelaces/internal/log" +) + +const ( + // InitTarget is an initial dummy target assigned to the servers + InitTarget = "NOTARGET" +) + +// Server holds data that uniquely identifies a server +type Server struct { + Mac string + IP string + Hostname string +} + +// Servers is an array of Server +type Servers []Server + +// Len implementation for the sort Interface +func (s Servers) Len() int { + return len(s) +} + +// Swap implementation for the sort interface +func (s Servers) Swap(i, j int) { + s[i], s[j] = s[j], s[i] +} + +// Less implementation for the Sort interface +func (s Servers) Less(i, j int) bool { + return s[i].Mac < s[j].Mac +} + +// State holds information regarding a host that is attempting to boot. +type State struct { + Server + Target string + Environment string + Params map[string]interface{} + Retry int + LastAccess int +} + +// States holds a map between MAC addresses and +// States. It provides a mutex for thread-safety. +type States struct { + sync.RWMutex + Servers map[string]*State +} + +// New returns a Server with is values initialized +func New(mac string, ip string, hostname string) Server { + return Server{ + Mac: mac, + IP: ip, + Hostname: hostname, + } +} + +// AddServer adds a server to the States struct +func (m *States) AddServer(server Server) { + m.Servers[server.Mac] = &State{ + Server: server, + Target: InitTarget, + Retry: 1, + LastAccess: int(time.Now().UTC().Unix()), + } +} + +// DeleteServer deletes a server from the States struct +func (m *States) DeleteServer(mac string) { + delete(m.Servers, mac) +} + +// StartStateCleaner spawns a goroutine that cleans MAC addresses that +// have been inactive in Shoelaces for more than 3 minutes. +func StartStateCleaner(logger log.Logger, serverStates *States) { + const ( + // 3 minutes + expireAfterSec = 3 * 60 + cleanInterval = time.Minute + ) + // Clean up the server states. Expire after 3 minutes + go func() { + for { + time.Sleep(cleanInterval) + + servers := serverStates.Servers + expire := int(time.Now().UTC().Unix()) - expireAfterSec + + logger.Debug("component", "polling", "msg", "Cleaning", "before", time.Unix(int64(expire), 0)) + + serverStates.Lock() + for mac, state := range servers { + if state.LastAccess <= expire { + delete(servers, mac) + logger.Debug("component", "polling", "msg", "Mac cleaned", "mac", mac) + } + } + serverStates.Unlock() + } + }() +} |