forked from gravitational/teleport
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathagent_store.go
102 lines (84 loc) · 2.44 KB
/
agent_store.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
/*
Copyright 2022 Gravitational, 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 reversetunnel
import (
"sync"
)
// agentStore handles adding and removing agents from an in memory store.
type agentStore struct {
agents []Agent
mu sync.RWMutex
}
// newAgentStore creates a new agentStore instance.
func newAgentStore() *agentStore {
return &agentStore{}
}
// len returns the number of agents in the store.
func (s *agentStore) len() int {
s.mu.RLock()
defer s.mu.RUnlock()
return len(s.agents)
}
// add adds an agent to the store.
func (s *agentStore) add(agent Agent) {
s.mu.Lock()
defer s.mu.Unlock()
s.agents = append(s.agents, agent)
}
// unsafeRemove removes an agent. Warning this is not threadsafe.
func (s *agentStore) unsafeRemove(agent Agent) bool {
for i := range s.agents {
if s.agents[i] != agent {
continue
}
s.agents = append(s.agents[:i], s.agents[i+1:]...)
return true
}
return false
}
// remove removes the given agent from the store.
func (s *agentStore) remove(agent Agent) bool {
s.mu.Lock()
defer s.mu.Unlock()
return s.unsafeRemove(agent)
}
// poplen pops an agent from the store if there are more agents in the store
// than the the given value. The oldest agent is always returned first.
func (s *agentStore) poplen(l int) (Agent, bool) {
s.mu.Lock()
defer s.mu.Unlock()
if l < 0 || len(s.agents) == 0 {
return nil, false
}
if len(s.agents) <= l {
return nil, false
}
agent := s.agents[0]
s.agents = s.agents[1:]
return agent, true
}
// proxyIDs returns a list of proxy ids that each agent is connected to ordered
// from newest to oldest connected proxy id.
func (s *agentStore) proxyIDs() []string {
s.mu.RLock()
defer s.mu.RUnlock()
ids := make([]string, 0, len(s.agents))
// New agents are always appended to the store so reversing the list
// orders the ids from newest to oldest.
for i := len(s.agents) - 1; i >= 0; i-- {
if id, ok := s.agents[i].GetProxyID(); ok {
ids = append(ids, id)
}
}
return ids
}