We need Connection.Shutdown to be non-blocked, and the way we achieved
this is by spawning a goroutine. However, there can be a potentially
unbounded number of Connection.Shutdown invocations. For example, if
the TCP connection has gone bad then any Connection.SendProtocolMsg
invocation will end up invoking Connection.Shutdown. There can be many
such invocations until the Connection has been removed from the
various data structures (e.g. LocalPeer.connections and
GossipSender.senders). Hence we can end up with with an unbounded
number of spawned goroutines.
To fix this, we introduce a one-element error channel on the
connection. Connection.Shutdown does a non-blocking send on that, and
the Connection.actorLoop reads from it and terminates.
This will throw away all but the first error encountered, but that is
fine and not much different from what was happening before (where we'd
throw away all but one of the errors encountered).
The same piece of GossipData can be shared and subject to different
Merge operations. We either need to copy the data when we share it, or
create copies on modification, i.e. copy-on-write.
We choose the latter, since it is more efficient and there is just one
mutating operation.
Fixes#1697.
This reverts commit 262352f8bb, reversing
changes made to 312691376a due to a bug
whereby `weave env` returns a unix domain socket with an incorrect path.
This change will be superceeded by #1694.
This lets you use -H unix://*.sock outside /var/run/weave. Using a
socket directly in /var/run (i.e. /var/run/foo.sock), will reintroduce
the bug with namespaces not being GCed, so that is a warning.
The deadlock described for SendProtocolMsg (if it was going via the
actor) cannot occur since all sending of broadcasts and gossip by
LocalPeer is mediated by GossipSenders, the interaction with which is
non-blocking.
Docker attempts to recreate networks on startup which means the plugin
container has to be started. If it isn't started automatically by Docker
with a restart policy, it's not possible to start it manually because
Docker is blocked.