From 77c172b823b64ebface655681ab0749b9d2f7081 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Benencia?= Date: Fri, 13 Apr 2018 16:30:31 -0700 Subject: First public commit --- internal/server/server.go | 123 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 internal/server/server.go (limited to 'internal/server/server.go') 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() + } + }() +} -- cgit v1.2.3