98 lines
2.4 KiB
Go
98 lines
2.4 KiB
Go
package models
|
|
|
|
import (
|
|
"git.wamblee.org/converge/pkg/comms"
|
|
"sort"
|
|
"sync/atomic"
|
|
"time"
|
|
)
|
|
|
|
type RendezVousId string
|
|
type AgentGuid string
|
|
type ClientGuid string
|
|
type ClientId string
|
|
type SessionType string
|
|
type RemoteAddr string
|
|
|
|
type Agent struct {
|
|
Guid AgentGuid
|
|
RemoteAddr RemoteAddr
|
|
PublicId RendezVousId
|
|
StartTime time.Time
|
|
EnvironmentInfo comms.EnvironmentInfo
|
|
expiryTime int64
|
|
}
|
|
|
|
func (agent *Agent) SetExpiryTime(t time.Time) {
|
|
atomic.StoreInt64(&agent.expiryTime, t.UnixNano())
|
|
}
|
|
|
|
func (agent *Agent) GetExpiryTime() time.Time {
|
|
t := atomic.LoadInt64(&agent.expiryTime)
|
|
return time.Unix(0, t)
|
|
}
|
|
|
|
type Client struct {
|
|
Guid ClientGuid
|
|
RemoteAddr RemoteAddr
|
|
PublicId RendezVousId
|
|
ClientId ClientId
|
|
AgentGuid AgentGuid
|
|
StartTime time.Time
|
|
SessionType SessionType
|
|
EnvironmentInfo comms.EnvironmentInfo
|
|
}
|
|
|
|
// State is a description of the current state of converge.
|
|
// Created by the matchmaker and used for updating the web client
|
|
// and prometheus metrics.
|
|
//
|
|
// Concurrency design:
|
|
// 1. State is immutable
|
|
// 2. The MatchMaker uses copy-on-write and never modifies a state directly.
|
|
// 3. the matchmaker modifies the expiry time of the agent. This is dealt with using the
|
|
// sync/atomic package by storing the expiry time as an int64 using time.Time.UnixNano()
|
|
|
|
type State struct {
|
|
Agents map[AgentGuid]*Agent
|
|
Clients map[ClientGuid]*Client
|
|
}
|
|
|
|
func NewState() *State {
|
|
return &State{
|
|
Agents: make(map[AgentGuid]*Agent),
|
|
Clients: make(map[ClientGuid]*Client),
|
|
}
|
|
}
|
|
|
|
// for copy on write
|
|
func (state *State) Copy() *State {
|
|
res := NewState()
|
|
for k, v := range state.Agents {
|
|
res.Agents[k] = v
|
|
}
|
|
for k, v := range state.Clients {
|
|
res.Clients[k] = v
|
|
}
|
|
return res
|
|
}
|
|
|
|
// Return agents and clients slices sorted on starttime ascending.
|
|
func (state *State) Slices() ([]*Agent, []*Client) {
|
|
agents := make([]*Agent, 0, len(state.Agents))
|
|
clients := make([]*Client, 0, len(state.Clients))
|
|
for _, agent := range state.Agents {
|
|
agents = append(agents, agent)
|
|
}
|
|
for _, client := range state.Clients {
|
|
clients = append(clients, client)
|
|
}
|
|
sort.Slice(agents, func(i int, j int) bool {
|
|
return agents[i].StartTime.Before(agents[j].StartTime)
|
|
})
|
|
sort.Slice(clients, func(i int, j int) bool {
|
|
return clients[i].StartTime.Before(clients[j].StartTime)
|
|
})
|
|
return agents, clients
|
|
}
|