This commit adds two command line options, intended to allow multiple
instances of weave to run without container separation between them.
* -port=PORT makes weave bind to port PORT (an integer). Without the
option, the default value (6783) is used.
* -httpaddr=ADDRESS makes weave bind its control interface to
a different address. For instance "127.0.0.1:6784" can be used to
bind to localhost only. An absent address element makes it bind to
all interfaces. ":6784" is the default. An empty string
can be used to disable the control interface.
Signed-off-by: Alex Bligh <alex@alex.org.uk>
This was a convenient but rather suspect coupling. In particular, it
will break if the period gossip logic changes s.t. it no longer sends
gossip on all connections every interval.
We were invoking AddConnection in a separate goroutine, and this could
result in RemoveConnection getting invoked first, resulting in bogus
entries in our connection map, which would effectively prevent
connectivity to the other peer until the stale entry got removed
through a lost tie break. And if, per chance, the remote end ran into
exactly the same race condition, then connectivity between that peer
and ourself was broken permanently.
Hitting this race condition required a combination of a) no UDP
heartbeat being received for HeartbeatTimeout(30s) - this causes the
actorLoop to terminate and RemoveConnection to be invoked, and b) the
AddConnection invocation getting delayed for at least that long.
...by obtaining our connection set just once. This also guards against
potential locking issues, since we no longer obtain the required
lock on our local peer while holding a lock on Peers.
Note that this change means the connection list can be out of date by
the time we enter Peers.ForEach. However, previously it was possible
for the list to change for each peer we are iterating over. So it's
just a different flavour of out-of-dateness.
Instead of following the usual actor pattern, we use a 1-place channel
with a non-blocking send. Essentially, if there is already a pending
recalculation request queued up, there is no point enqueuing another
one.
we simply reset the vars controlling backoff for that address
Note that we do not interrupt any current connection attempt, since
that is hard.
Closes#499.
d5eb76f32 replaced (*Peer)ForEachConnection into (*Peer)Connections(),
and consequently converted some nested functions into for loops. But
the "return" statements in those nested functions were left as-was,
and so exited the outer function rather than moving on to the next
iteration.
Fixes#497
The previous scheme set the reference to main channel to nil and then
drained it. That was racy and hence could lead to deadlock in the
following scenario:
1. multiple senders obtain the main channel from the stored reference
2. main channel reference is set to nil
3. main channel is drained
4. multiple senders send to main channel
So the issue here is that the entire forwarder stopping sequence
occurs between senders obtaining of the reference to the main channel,
and then sending on that channel. If more senders sent than there is
capacity in the channel then this leads to deadlock.