186 lines
4.5 KiB
Go
186 lines
4.5 KiB
Go
/*
|
|
* Copyright 2020 The Dragonfly Authors
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
//go:generate mockgen -destination ./mocks/host_mock.go -package mocks d7y.io/dragonfly/v2/scheduler/supervisor HostManager
|
|
|
|
package supervisor
|
|
|
|
import (
|
|
"sync"
|
|
|
|
logger "d7y.io/dragonfly/v2/internal/dflog"
|
|
"go.uber.org/atomic"
|
|
)
|
|
|
|
type HostManager interface {
|
|
// Add host
|
|
Add(*Host)
|
|
// Get host
|
|
Get(string) (*Host, bool)
|
|
// Delete host
|
|
Delete(string)
|
|
}
|
|
|
|
type hostManager struct {
|
|
// host map
|
|
*sync.Map
|
|
}
|
|
|
|
func NewHostManager() HostManager {
|
|
return &hostManager{&sync.Map{}}
|
|
}
|
|
|
|
func (m *hostManager) Get(key string) (*Host, bool) {
|
|
host, ok := m.Load(key)
|
|
if !ok {
|
|
return nil, false
|
|
}
|
|
|
|
return host.(*Host), ok
|
|
}
|
|
|
|
func (m *hostManager) Add(host *Host) {
|
|
m.Store(host.UUID, host)
|
|
}
|
|
|
|
func (m *hostManager) Delete(key string) {
|
|
m.Map.Delete(key)
|
|
}
|
|
|
|
type HostOption func(rt *Host) *Host
|
|
|
|
func WithTotalUploadLoad(load int32) HostOption {
|
|
return func(h *Host) *Host {
|
|
h.TotalUploadLoad = load
|
|
return h
|
|
}
|
|
}
|
|
|
|
func WithNetTopology(n string) HostOption {
|
|
return func(h *Host) *Host {
|
|
h.NetTopology = n
|
|
return h
|
|
}
|
|
}
|
|
|
|
type Host struct {
|
|
// uuid each time the daemon starts, it will generate a different uuid
|
|
UUID string
|
|
// IP peer host ip
|
|
IP string
|
|
// HostName peer host name
|
|
HostName string
|
|
// RPCPort rpc service port for peer
|
|
RPCPort int32
|
|
// DownloadPort piece downloading port for peer
|
|
DownloadPort int32
|
|
// IsCDN if host type is cdn
|
|
IsCDN bool
|
|
// SecurityDomain security isolation domain for network
|
|
SecurityDomain string
|
|
// Location location path: area|country|province|city|...
|
|
Location string
|
|
// IDC idc where the peer host is located
|
|
IDC string
|
|
// NetTopology network device path
|
|
// according to the user's own network topology definition, the coverage range from large to small, using the | symbol segmentation,
|
|
// Example: switch|router|...
|
|
NetTopology string
|
|
// TODO TotalUploadLoad currentUploadLoad decided by real time client report host info
|
|
TotalUploadLoad int32
|
|
// CurrentUploadLoad is current upload load number
|
|
CurrentUploadLoad atomic.Int32
|
|
// peers info map
|
|
peers *sync.Map
|
|
// host logger
|
|
logger *logger.SugaredLoggerOnWith
|
|
}
|
|
|
|
func NewClientHost(uuid, ip, hostname string, rpcPort, downloadPort int32, securityDomain, location, idc string, options ...HostOption) *Host {
|
|
return newHost(uuid, ip, hostname, rpcPort, downloadPort, false, securityDomain, location, idc, options...)
|
|
}
|
|
|
|
func NewCDNHost(uuid, ip, hostname string, rpcPort, downloadPort int32, securityDomain, location, idc string, options ...HostOption) *Host {
|
|
return newHost(uuid, ip, hostname, rpcPort, downloadPort, true, securityDomain, location, idc, options...)
|
|
}
|
|
|
|
func newHost(uuid, ip, hostname string, rpcPort, downloadPort int32, isCDN bool, securityDomain, location, idc string, options ...HostOption) *Host {
|
|
host := &Host{
|
|
UUID: uuid,
|
|
IP: ip,
|
|
HostName: hostname,
|
|
RPCPort: rpcPort,
|
|
DownloadPort: downloadPort,
|
|
IsCDN: isCDN,
|
|
SecurityDomain: securityDomain,
|
|
Location: location,
|
|
IDC: idc,
|
|
NetTopology: "",
|
|
TotalUploadLoad: 100,
|
|
peers: &sync.Map{},
|
|
logger: logger.With("hostUUID", uuid),
|
|
}
|
|
|
|
for _, opt := range options {
|
|
opt(host)
|
|
}
|
|
|
|
return host
|
|
}
|
|
|
|
func (h *Host) AddPeer(peer *Peer) {
|
|
h.peers.Store(peer.ID, peer)
|
|
}
|
|
|
|
func (h *Host) DeletePeer(id string) {
|
|
h.peers.Delete(id)
|
|
}
|
|
|
|
func (h *Host) GetPeer(id string) (*Peer, bool) {
|
|
peer, ok := h.peers.Load(id)
|
|
if !ok {
|
|
return nil, false
|
|
}
|
|
|
|
return peer.(*Peer), ok
|
|
}
|
|
|
|
func (h *Host) GetPeersLen() int {
|
|
length := 0
|
|
h.peers.Range(func(_, _ interface{}) bool {
|
|
length++
|
|
return true
|
|
})
|
|
|
|
return length
|
|
}
|
|
|
|
func (h *Host) GetUploadLoadPercent() float64 {
|
|
if h.TotalUploadLoad <= 0 {
|
|
return 1.0
|
|
}
|
|
|
|
return float64(h.CurrentUploadLoad.Load()) / float64(h.TotalUploadLoad)
|
|
}
|
|
|
|
func (h *Host) GetFreeUploadLoad() int32 {
|
|
return h.TotalUploadLoad - h.CurrentUploadLoad.Load()
|
|
}
|
|
|
|
func (h *Host) Log() *logger.SugaredLoggerOnWith {
|
|
return h.logger
|
|
}
|