mirror of
https://github.com/PeernetOfficial/core.git
synced 2026-07-17 02:47:51 +01:00
Connections: Introduce Redundant type to lower ping overhead.
This commit is contained in:
42
Commands.go
42
Commands.go
@@ -88,7 +88,7 @@ func (peer *PeerInfo) cmdChat(msg *packet2) {
|
||||
const pingTime = 10
|
||||
|
||||
// connectionInvalidate is the threshold in seconds to invalidate formerly active connections that no longer receive incoming packets.
|
||||
const connectionInvalidate = 20
|
||||
const connectionInvalidate = 22
|
||||
|
||||
// connectionRemove is the threshold in seconds to remove inactive connections in case there is at least one active connection known.
|
||||
const connectionRemove = 2 * 60
|
||||
@@ -97,24 +97,29 @@ const connectionRemove = 2 * 60
|
||||
func autoPingAll() {
|
||||
for {
|
||||
time.Sleep(time.Second)
|
||||
thresholdInvalidate := time.Now().Add(-connectionInvalidate * time.Second)
|
||||
thresholdPingOut := time.Now().Add(-pingTime * time.Second)
|
||||
thresholdInvalidate1 := time.Now().Add(-connectionInvalidate * time.Second)
|
||||
thresholdInvalidate2 := time.Now().Add(-connectionInvalidate * time.Second * 4)
|
||||
thresholdPingOut1 := time.Now().Add(-pingTime * time.Second)
|
||||
thresholdPingOut2 := time.Now().Add(-pingTime * time.Second * 4)
|
||||
|
||||
for _, peer := range PeerlistGet() {
|
||||
// first handle active connections
|
||||
for _, connection := range peer.GetConnections(true) {
|
||||
// Check if no incoming packet for the last X seconds. Regularly sent pings should result in incoming packets.
|
||||
if connection.LastPacketIn.Before(thresholdInvalidate) {
|
||||
thresholdPing := thresholdPingOut1
|
||||
thresholdInv := thresholdInvalidate1
|
||||
|
||||
if connection.Status == ConnectionRedundant {
|
||||
thresholdPing = thresholdPingOut2
|
||||
thresholdInv = thresholdInvalidate2
|
||||
}
|
||||
|
||||
if connection.LastPacketIn.Before(thresholdInv) {
|
||||
peer.invalidateActiveConnection(connection)
|
||||
continue
|
||||
}
|
||||
|
||||
// Send ping if none was sent recently and no incoming packet was received recently.
|
||||
if connection.LastPacketIn.Before(thresholdPingOut) && connection.LastPingOut.Before(thresholdPingOut) {
|
||||
if err := peer.sendConnection(&PacketRaw{Command: CommandPing}, connection); IsNetworkErrorFatal(err) {
|
||||
peer.invalidateActiveConnection(connection)
|
||||
}
|
||||
connection.LastPingOut = time.Now()
|
||||
if connection.LastPacketIn.Before(thresholdPing) && connection.LastPingOut.Before(thresholdPing) {
|
||||
peer.sendPing(connection)
|
||||
continue
|
||||
}
|
||||
}
|
||||
@@ -128,15 +133,24 @@ func autoPingAll() {
|
||||
}
|
||||
|
||||
// if no ping was sent recently, send one now
|
||||
if connection.LastPingOut.Before(thresholdPingOut) {
|
||||
peer.sendConnection(&PacketRaw{Command: CommandPing}, connection)
|
||||
connection.LastPingOut = time.Now()
|
||||
if connection.LastPingOut.Before(thresholdPingOut1) {
|
||||
peer.sendPing(connection)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sendPing sends a ping to the target peer
|
||||
func (peer *PeerInfo) sendPing(connection *Connection) {
|
||||
err := peer.sendConnection(&PacketRaw{Command: CommandPing}, connection)
|
||||
connection.LastPingOut = time.Now()
|
||||
|
||||
if (connection.Status == ConnectionActive || connection.Status == ConnectionRedundant) && IsNetworkErrorFatal(err) {
|
||||
peer.invalidateActiveConnection(connection)
|
||||
}
|
||||
}
|
||||
|
||||
// SendChatAll sends a text message to all peers
|
||||
func SendChatAll(text string) {
|
||||
for _, peer := range PeerlistGet() {
|
||||
|
||||
@@ -24,7 +24,7 @@ type Connection struct {
|
||||
LastPacketOut time.Time // Last time an outgoing packet was attempted to send.
|
||||
LastPingOut time.Time // Last ping out.
|
||||
Expires time.Time // Inactive connections only: Expiry date. If it does not become active by that date, it will be considered expired and removed.
|
||||
Status int // 0 = Active established connection, 1 = Inactive, 2 = Removed
|
||||
Status int // 0 = Active established connection, 1 = Inactive, 2 = Removed, 3 = Redundant
|
||||
}
|
||||
|
||||
// Connection status
|
||||
@@ -32,6 +32,7 @@ const (
|
||||
ConnectionActive = iota
|
||||
ConnectionInactive
|
||||
ConnectionRemoved
|
||||
ConnectionRedundant // Same as active. Incoming packets are accepted. Outgoing use only for redundancy. Reduces ping overhead.
|
||||
)
|
||||
|
||||
// Equal checks if the connection was established other the same network adapter using the same IP address. Port is intentionally not checked.
|
||||
@@ -64,7 +65,8 @@ func (peer *PeerInfo) registerConnection(incoming *Connection) (result *Connecti
|
||||
connection.Address.Port = incoming.Address.Port
|
||||
}
|
||||
|
||||
peer.connectionLatest = connection
|
||||
connection.Status = ConnectionActive
|
||||
peer.setConnectionLatest(connection)
|
||||
return connection
|
||||
}
|
||||
}
|
||||
@@ -78,8 +80,8 @@ func (peer *PeerInfo) registerConnection(incoming *Connection) (result *Connecti
|
||||
|
||||
// elevate by adding to active and mark as latest active
|
||||
connection.Status = ConnectionActive
|
||||
peer.connectionLatest = connection
|
||||
peer.connectionActive = append(peer.connectionActive, connection)
|
||||
peer.setConnectionLatest(connection)
|
||||
|
||||
// remove from inactive
|
||||
inactiveNew := peer.connectionInactive[:n]
|
||||
@@ -94,11 +96,27 @@ func (peer *PeerInfo) registerConnection(incoming *Connection) (result *Connecti
|
||||
|
||||
// otherwise it is a new connection!
|
||||
peer.connectionActive = append(peer.connectionActive, incoming)
|
||||
peer.connectionLatest = incoming
|
||||
peer.setConnectionLatest(incoming)
|
||||
|
||||
return incoming
|
||||
}
|
||||
|
||||
// setConnectionLatest updates the latest valid connection to use for sending. All other connections will be changed to redundant, which reduces ping overhead.
|
||||
func (peer *PeerInfo) setConnectionLatest(latest *Connection) {
|
||||
if peer.connectionLatest == latest {
|
||||
return
|
||||
}
|
||||
|
||||
peer.connectionLatest = latest
|
||||
|
||||
for _, connection := range peer.connectionActive {
|
||||
if connection == latest {
|
||||
continue
|
||||
}
|
||||
connection.Status = ConnectionRedundant
|
||||
}
|
||||
}
|
||||
|
||||
// invalidateActiveConnection invalidates an active connection
|
||||
func (peer *PeerInfo) invalidateActiveConnection(input *Connection) {
|
||||
peer.Lock()
|
||||
|
||||
Reference in New Issue
Block a user