Repository navigation
Seed the address pool when an outbound connection finds no address. - #924
echennells wants to merge 1 commit into
Conversation
3507963 to
1a3a033
Compare
|
Looks promising, we need this fix. But first let's figure out why a network drop doesn't preserve addresses. That's an error code filtering issue. It's not only timeouts that should get returned to the pool, it's any failure that's not attributable to the address itself. |
| BC_ASSERT(stranded()); | ||
|
|
||
| // A seed session ends within the seeding timeout, so this also precludes | ||
| // concurrent sessions. |
There was a problem hiding this comment.
This is too fragile for async programming. The seeding session can run forever, despite having a timeout, as closure is dependent upon the ASIO message queue, which can become backlogged. This would start up new sessions as previous ones are trying to stop, and that could lead to an unguarded backlog that would eventually bring down the process.
What you are after is idempotency and a definitive state to base that on: running or not running. That requires a seed session completion handler to bounce back to the calling strand and update a bool (e.g. seeding_), which must be checked (idempotent) and updated by the start.
|
|
||
| // The session logs its own result, and a failure is retried on demand. | ||
| seeded_ = now; | ||
| attach_seed_session()->start([](const code&) NOEXCEPT {}); |
There was a problem hiding this comment.
IIRC the no-op handler being passed is the completion event that you need.
1a3a033 to
40deacf
Compare
|
Thanks. Two parts. Why a network drop loses addresses: #942. An outage fails connects with Seeding guard: the timeout is gone. As you suggested, the state is contained in the seed session: Would you rather the seed session reseed itself, keeping all of this within it? |
|
Retaining the seed session and gating on
On having the seed session reseed itself: no, keep the trigger in outbound. Outbound is the only place that observes a failed |
40deacf to
ce33a1c
Compare
|
Thanks, changes:
Tests start the network, so the startup session is retained: a sufficient count or no seeds give no reseed; a running or just-completed session, startup or reseeded, blocks the next; otherwise each call reseeds. |
On an empty address pool the outbound session defers and retries, relying on peer gossip to refill it. With no channels nothing refills it, and as seeding runs only at startup, outbound connections stall until a manual or inbound peer connects. #942 keeps an outage from emptying the pool; this is the fallback when it empties anyway.
The outbound session now also seeds when it finds no address. The network retains its seed session, as it does the manual session;
session_seed::seeding()is true from seed connection start untilstop_seed, once all have stopped, so one session runs at a time by completion rather than timing. The startup session is retained the same way.A new session starts only if the network is open, seeds are configured, the pool is below its minimum (as
address_not_foundalso covers a pool with nothing usable for the slot), the retained session is not seeding, and none completed within 10 seeding timeouts.