autopilot/agent: add maps to agent struct
This commit moves the maps used by the controller loop to the Agent struct, in preparation for breaking it up into smaller parts.
This commit is contained in:
parent
86e6d230f2
commit
fb10175ea5
@ -143,6 +143,22 @@ type Agent struct {
|
|||||||
// when the agent receives external balance update signals.
|
// when the agent receives external balance update signals.
|
||||||
totalBalance btcutil.Amount
|
totalBalance btcutil.Amount
|
||||||
|
|
||||||
|
// failedNodes lists nodes that we've previously attempted to initiate
|
||||||
|
// channels with, but didn't succeed.
|
||||||
|
failedNodes map[NodeID]struct{}
|
||||||
|
|
||||||
|
// pendingConns tracks the nodes that we are attempting to make
|
||||||
|
// connections to. This prevents us from making duplicate connection
|
||||||
|
// requests to the same node.
|
||||||
|
pendingConns map[NodeID]struct{}
|
||||||
|
|
||||||
|
// pendingOpens tracks the channels that we've requested to be
|
||||||
|
// initiated, but haven't yet been confirmed as being fully opened.
|
||||||
|
// This state is required as otherwise, we may go over our allotted
|
||||||
|
// channel limit, or open multiple channels to the same node.
|
||||||
|
pendingOpens map[NodeID]Channel
|
||||||
|
pendingMtx sync.Mutex
|
||||||
|
|
||||||
quit chan struct{}
|
quit chan struct{}
|
||||||
wg sync.WaitGroup
|
wg sync.WaitGroup
|
||||||
}
|
}
|
||||||
@ -161,6 +177,9 @@ func New(cfg Config, initialState []Channel) (*Agent, error) {
|
|||||||
nodeUpdates: make(chan *nodeUpdates, 1),
|
nodeUpdates: make(chan *nodeUpdates, 1),
|
||||||
chanOpenFailures: make(chan *chanOpenFailureUpdate, 1),
|
chanOpenFailures: make(chan *chanOpenFailureUpdate, 1),
|
||||||
pendingOpenUpdates: make(chan *chanPendingOpenUpdate, 1),
|
pendingOpenUpdates: make(chan *chanPendingOpenUpdate, 1),
|
||||||
|
failedNodes: make(map[NodeID]struct{}),
|
||||||
|
pendingConns: make(map[NodeID]struct{}),
|
||||||
|
pendingOpens: make(map[NodeID]Channel),
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, c := range initialState {
|
for _, c := range initialState {
|
||||||
@ -357,23 +376,6 @@ func (a *Agent) controller() {
|
|||||||
|
|
||||||
// TODO(roasbeef): do we in fact need to maintain order?
|
// TODO(roasbeef): do we in fact need to maintain order?
|
||||||
// * use sync.Cond if so
|
// * use sync.Cond if so
|
||||||
|
|
||||||
// failedNodes lists nodes that we've previously attempted to initiate
|
|
||||||
// channels with, but didn't succeed.
|
|
||||||
failedNodes := make(map[NodeID]struct{})
|
|
||||||
|
|
||||||
// pendingConns tracks the nodes that we are attempting to make
|
|
||||||
// connections to. This prevents us from making duplicate connection
|
|
||||||
// requests to the same node.
|
|
||||||
pendingConns := make(map[NodeID]struct{})
|
|
||||||
|
|
||||||
// pendingOpens tracks the channels that we've requested to be
|
|
||||||
// initiated, but haven't yet been confirmed as being fully opened.
|
|
||||||
// This state is required as otherwise, we may go over our allotted
|
|
||||||
// channel limit, or open multiple channels to the same node.
|
|
||||||
pendingOpens := make(map[NodeID]Channel)
|
|
||||||
var pendingMtx sync.Mutex
|
|
||||||
|
|
||||||
updateBalance := func() {
|
updateBalance := func() {
|
||||||
newBalance, err := a.cfg.WalletBalance()
|
newBalance, err := a.cfg.WalletBalance()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -405,9 +407,9 @@ func (a *Agent) controller() {
|
|||||||
newChan := update.newChan
|
newChan := update.newChan
|
||||||
a.chanState[newChan.ChanID] = newChan
|
a.chanState[newChan.ChanID] = newChan
|
||||||
|
|
||||||
pendingMtx.Lock()
|
a.pendingMtx.Lock()
|
||||||
delete(pendingOpens, newChan.Node)
|
delete(a.pendingOpens, newChan.Node)
|
||||||
pendingMtx.Unlock()
|
a.pendingMtx.Unlock()
|
||||||
|
|
||||||
updateBalance()
|
updateBalance()
|
||||||
// A channel has been closed, this may free up an
|
// A channel has been closed, this may free up an
|
||||||
@ -458,17 +460,17 @@ func (a *Agent) controller() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
pendingMtx.Lock()
|
a.pendingMtx.Lock()
|
||||||
log.Debugf("Pending channels: %v", spew.Sdump(pendingOpens))
|
log.Debugf("Pending channels: %v", spew.Sdump(a.pendingOpens))
|
||||||
pendingMtx.Unlock()
|
a.pendingMtx.Unlock()
|
||||||
|
|
||||||
// With all the updates applied, we'll obtain a set of the
|
// With all the updates applied, we'll obtain a set of the
|
||||||
// current active channels (confirmed channels), and also
|
// current active channels (confirmed channels), and also
|
||||||
// factor in our set of unconfirmed channels.
|
// factor in our set of unconfirmed channels.
|
||||||
confirmedChans := a.chanState
|
confirmedChans := a.chanState
|
||||||
pendingMtx.Lock()
|
a.pendingMtx.Lock()
|
||||||
totalChans := mergeChanState(pendingOpens, confirmedChans)
|
totalChans := mergeChanState(a.pendingOpens, confirmedChans)
|
||||||
pendingMtx.Unlock()
|
a.pendingMtx.Unlock()
|
||||||
|
|
||||||
// Now that we've updated our internal state, we'll consult our
|
// Now that we've updated our internal state, we'll consult our
|
||||||
// channel attachment heuristic to determine if we should open
|
// channel attachment heuristic to determine if we should open
|
||||||
@ -487,11 +489,11 @@ func (a *Agent) controller() {
|
|||||||
// nodes that we currently have channels with so we avoid
|
// nodes that we currently have channels with so we avoid
|
||||||
// duplicate edges.
|
// duplicate edges.
|
||||||
connectedNodes := a.chanState.ConnectedNodes()
|
connectedNodes := a.chanState.ConnectedNodes()
|
||||||
pendingMtx.Lock()
|
a.pendingMtx.Lock()
|
||||||
nodesToSkip := mergeNodeMaps(pendingOpens,
|
nodesToSkip := mergeNodeMaps(a.pendingOpens,
|
||||||
pendingConns, connectedNodes, failedNodes,
|
a.pendingConns, connectedNodes, a.failedNodes,
|
||||||
)
|
)
|
||||||
pendingMtx.Unlock()
|
a.pendingMtx.Unlock()
|
||||||
|
|
||||||
// If we reach this point, then according to our heuristic we
|
// If we reach this point, then according to our heuristic we
|
||||||
// should modify our channel state to tend towards what it
|
// should modify our channel state to tend towards what it
|
||||||
@ -522,9 +524,9 @@ func (a *Agent) controller() {
|
|||||||
// certain which ones may actually succeed. If too many
|
// certain which ones may actually succeed. If too many
|
||||||
// connections succeed, we will they will be ignored and made
|
// connections succeed, we will they will be ignored and made
|
||||||
// available to future heuristic selections.
|
// available to future heuristic selections.
|
||||||
pendingMtx.Lock()
|
a.pendingMtx.Lock()
|
||||||
if uint16(len(pendingOpens)) >= a.cfg.Constraints.MaxPendingOpens {
|
if uint16(len(a.pendingOpens)) >= a.cfg.Constraints.MaxPendingOpens {
|
||||||
pendingMtx.Unlock()
|
a.pendingMtx.Unlock()
|
||||||
log.Debugf("Reached cap of %v pending "+
|
log.Debugf("Reached cap of %v pending "+
|
||||||
"channel opens, will retry "+
|
"channel opens, will retry "+
|
||||||
"after success/failure",
|
"after success/failure",
|
||||||
@ -540,10 +542,10 @@ func (a *Agent) controller() {
|
|||||||
// Skip candidates which we are already trying
|
// Skip candidates which we are already trying
|
||||||
// to establish a connection with.
|
// to establish a connection with.
|
||||||
nodeID := chanCandidate.NodeID
|
nodeID := chanCandidate.NodeID
|
||||||
if _, ok := pendingConns[nodeID]; ok {
|
if _, ok := a.pendingConns[nodeID]; ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
pendingConns[nodeID] = struct{}{}
|
a.pendingConns[nodeID] = struct{}{}
|
||||||
|
|
||||||
a.wg.Add(1)
|
a.wg.Add(1)
|
||||||
go func(directive AttachmentDirective) {
|
go func(directive AttachmentDirective) {
|
||||||
@ -567,10 +569,10 @@ func (a *Agent) controller() {
|
|||||||
// don't attempt to connect to them
|
// don't attempt to connect to them
|
||||||
// again.
|
// again.
|
||||||
nodeID := NewNodeID(pub)
|
nodeID := NewNodeID(pub)
|
||||||
pendingMtx.Lock()
|
a.pendingMtx.Lock()
|
||||||
delete(pendingConns, nodeID)
|
delete(a.pendingConns, nodeID)
|
||||||
failedNodes[nodeID] = struct{}{}
|
a.failedNodes[nodeID] = struct{}{}
|
||||||
pendingMtx.Unlock()
|
a.pendingMtx.Unlock()
|
||||||
|
|
||||||
// Finally, we'll trigger the agent to
|
// Finally, we'll trigger the agent to
|
||||||
// select new peers to connect to.
|
// select new peers to connect to.
|
||||||
@ -586,8 +588,8 @@ func (a *Agent) controller() {
|
|||||||
// directives were spawned but fewer slots were
|
// directives were spawned but fewer slots were
|
||||||
// available, and other successful attempts
|
// available, and other successful attempts
|
||||||
// finished first.
|
// finished first.
|
||||||
pendingMtx.Lock()
|
a.pendingMtx.Lock()
|
||||||
if uint16(len(pendingOpens)) >=
|
if uint16(len(a.pendingOpens)) >=
|
||||||
a.cfg.Constraints.MaxPendingOpens {
|
a.cfg.Constraints.MaxPendingOpens {
|
||||||
// Since we've reached our max number of
|
// Since we've reached our max number of
|
||||||
// pending opens, we'll disconnect this
|
// pending opens, we'll disconnect this
|
||||||
@ -600,10 +602,10 @@ func (a *Agent) controller() {
|
|||||||
// connecting, we won't add this
|
// connecting, we won't add this
|
||||||
// peer to the failed nodes map,
|
// peer to the failed nodes map,
|
||||||
// but we will remove it from
|
// but we will remove it from
|
||||||
// pendingConns so that it can
|
// a.pendingConns so that it can
|
||||||
// be retried in the future.
|
// be retried in the future.
|
||||||
delete(pendingConns, nodeID)
|
delete(a.pendingConns, nodeID)
|
||||||
pendingMtx.Unlock()
|
a.pendingMtx.Unlock()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -622,8 +624,8 @@ func (a *Agent) controller() {
|
|||||||
// remove this node from our pending
|
// remove this node from our pending
|
||||||
// conns map, permitting subsequent
|
// conns map, permitting subsequent
|
||||||
// connection attempts.
|
// connection attempts.
|
||||||
delete(pendingConns, nodeID)
|
delete(a.pendingConns, nodeID)
|
||||||
pendingMtx.Unlock()
|
a.pendingMtx.Unlock()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -633,12 +635,12 @@ func (a *Agent) controller() {
|
|||||||
// peers if the connection attempt happens to
|
// peers if the connection attempt happens to
|
||||||
// take too long.
|
// take too long.
|
||||||
nodeID := directive.NodeID
|
nodeID := directive.NodeID
|
||||||
delete(pendingConns, nodeID)
|
delete(a.pendingConns, nodeID)
|
||||||
pendingOpens[nodeID] = Channel{
|
a.pendingOpens[nodeID] = Channel{
|
||||||
Capacity: directive.ChanAmt,
|
Capacity: directive.ChanAmt,
|
||||||
Node: nodeID,
|
Node: nodeID,
|
||||||
}
|
}
|
||||||
pendingMtx.Unlock()
|
a.pendingMtx.Unlock()
|
||||||
|
|
||||||
// We can then begin the funding workflow with
|
// We can then begin the funding workflow with
|
||||||
// this peer.
|
// this peer.
|
||||||
@ -656,10 +658,10 @@ func (a *Agent) controller() {
|
|||||||
// opens and mark them as failed so we
|
// opens and mark them as failed so we
|
||||||
// don't attempt to open a channel to
|
// don't attempt to open a channel to
|
||||||
// them again.
|
// them again.
|
||||||
pendingMtx.Lock()
|
a.pendingMtx.Lock()
|
||||||
delete(pendingOpens, nodeID)
|
delete(a.pendingOpens, nodeID)
|
||||||
failedNodes[nodeID] = struct{}{}
|
a.failedNodes[nodeID] = struct{}{}
|
||||||
pendingMtx.Unlock()
|
a.pendingMtx.Unlock()
|
||||||
|
|
||||||
// Trigger the agent to re-evaluate
|
// Trigger the agent to re-evaluate
|
||||||
// everything and possibly retry with a
|
// everything and possibly retry with a
|
||||||
@ -690,7 +692,7 @@ func (a *Agent) controller() {
|
|||||||
a.OnChannelPendingOpen()
|
a.OnChannelPendingOpen()
|
||||||
}(chanCandidate)
|
}(chanCandidate)
|
||||||
}
|
}
|
||||||
pendingMtx.Unlock()
|
a.pendingMtx.Unlock()
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user