forked from libp2p/go-libp2p
-
Notifications
You must be signed in to change notification settings - Fork 0
/
extapi.go
147 lines (118 loc) · 3.37 KB
/
extapi.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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
package rcmgr
import (
"bytes"
"sort"
"strings"
"github.com/libp2p/go-libp2p/core/network"
"github.com/libp2p/go-libp2p/core/peer"
"github.com/libp2p/go-libp2p/core/protocol"
)
// ResourceScopeLimiter is a trait interface that allows you to access scope limits.
type ResourceScopeLimiter interface {
Limit() Limit
SetLimit(Limit)
}
var _ ResourceScopeLimiter = (*resourceScope)(nil)
// ResourceManagerStat is a trait that allows you to access resource manager state.
type ResourceManagerState interface {
ListServices() []string
ListProtocols() []protocol.ID
ListPeers() []peer.ID
Stat() ResourceManagerStat
}
type ResourceManagerStat struct {
System network.ScopeStat
Transient network.ScopeStat
Services map[string]network.ScopeStat
Protocols map[protocol.ID]network.ScopeStat
Peers map[peer.ID]network.ScopeStat
}
var _ ResourceManagerState = (*resourceManager)(nil)
func (s *resourceScope) Limit() Limit {
s.Lock()
defer s.Unlock()
return s.rc.limit
}
func (s *resourceScope) SetLimit(limit Limit) {
s.Lock()
defer s.Unlock()
s.rc.limit = limit
}
func (s *protocolScope) SetLimit(limit Limit) {
s.rcmgr.setStickyProtocol(s.proto)
s.resourceScope.SetLimit(limit)
}
func (s *peerScope) SetLimit(limit Limit) {
s.rcmgr.setStickyPeer(s.peer)
s.resourceScope.SetLimit(limit)
}
func (r *resourceManager) ListServices() []string {
r.mx.Lock()
defer r.mx.Unlock()
result := make([]string, 0, len(r.svc))
for svc := range r.svc {
result = append(result, svc)
}
sort.Slice(result, func(i, j int) bool {
return strings.Compare(result[i], result[j]) < 0
})
return result
}
func (r *resourceManager) ListProtocols() []protocol.ID {
r.mx.Lock()
defer r.mx.Unlock()
result := make([]protocol.ID, 0, len(r.proto))
for p := range r.proto {
result = append(result, p)
}
sort.Slice(result, func(i, j int) bool {
return result[i] < result[j]
})
return result
}
func (r *resourceManager) ListPeers() []peer.ID {
r.mx.Lock()
defer r.mx.Unlock()
result := make([]peer.ID, 0, len(r.peer))
for p := range r.peer {
result = append(result, p)
}
sort.Slice(result, func(i, j int) bool {
return bytes.Compare([]byte(result[i]), []byte(result[j])) < 0
})
return result
}
func (r *resourceManager) Stat() (result ResourceManagerStat) {
r.mx.Lock()
svcs := make([]*serviceScope, 0, len(r.svc))
for _, svc := range r.svc {
svcs = append(svcs, svc)
}
protos := make([]*protocolScope, 0, len(r.proto))
for _, proto := range r.proto {
protos = append(protos, proto)
}
peers := make([]*peerScope, 0, len(r.peer))
for _, peer := range r.peer {
peers = append(peers, peer)
}
r.mx.Unlock()
// Note: there is no global lock, so the system is updating while we are dumping its state...
// as such stats might not exactly add up to the system level; we take the system stat
// last nonetheless so that this is the most up-to-date snapshot
result.Peers = make(map[peer.ID]network.ScopeStat, len(peers))
for _, peer := range peers {
result.Peers[peer.peer] = peer.Stat()
}
result.Protocols = make(map[protocol.ID]network.ScopeStat, len(protos))
for _, proto := range protos {
result.Protocols[proto.proto] = proto.Stat()
}
result.Services = make(map[string]network.ScopeStat, len(svcs))
for _, svc := range svcs {
result.Services[svc.service] = svc.Stat()
}
result.Transient = r.transient.Stat()
result.System = r.system.Stat()
return result
}