Closed Stebalien closed 2 years ago
This addresses https://github.com/ipfs/go-bitswap/issues/547 right?
Yes. Ideally we would be using the event bus, not callback-based notifications, but this "fixes" the issue (even if it doesn't pay down all the technical debt).
Note: while this PR has a number of failing tests preliminary production tests have shown it works and unfortunately this repo has a lot of flaky tests that we need to deal with such as https://github.com/ipfs/go-libipfs/issues/86
Motivation
This change handles connectedness and responsiveness events asynchronously, coalescing multiple state-changes into one. In the past, this area has caused quite a bit of goroutine buildup as we fall behind processing connect and disconnect events.
Design
The design is a simple state-machine with the following components:
A record of the current and "new" state for each peer.
A queue of peers that have "changed".
A worker that applies state transitions.
When an event (disconnect, connect, unresponsive, responsive) happens, we record the desired (new) state for that peer and enqueue the peer for further processing by the background worker.
The background worker takes peers off the background task queue, applying state-changes.
Importantly:
OnMessage
is called all the time, so this is pretty important.One drawback to not using a channel is that we have a global lock which may end up getting contended. However, we only hold the lock for very short periods of time, so this should be fine (testing TBD).