* When routers change (connect/disconnect), we re-check the mesh. We are passing in the routers to the channel and they can build up, which is unnecessary. We only need to signal once for all the routers that change since the last time we checked, that the mesh needs to be checked.
* We pass link changes through the run method, which is unnecessary since we pass it to a new goroutine. This inefficiency should be fixed.
* We're evaluating all faulted links for rerouting, even if they were still pending. Only reroute connected links.
* We're using time.After in each for loop, which can accumulate timers. Use a single Ticker instead.
Previously we often had two sets of events, one in the network
package, and then another in the events package. We now only
have one, in the events package. Events now have a public API,
with minimal deps. There's an implementation package which has
the dependencies. This allows the network package to generate
events, without have a circular dependency on the events
implementation package.