Refactor(jd-client): replace monolithic start loop with JdcRuntime typestate machine - #633
Conversation
27713eb to
45f79e5
Compare
|
A note: in the initial sketch, |
7dcc7ee to
5dd1782
Compare
5dd1782 to
ec4544a
Compare
537c0ef to
2f72d3f
Compare
cd17528 to
94901fa
Compare
58c6041 to
76461a0
Compare
50b7941 to
93be0b3
Compare
bit-aloo
left a comment
There was a problem hiding this comment.
Some suggestions, we are pretty close.
| if let Some(monitoring_addr) = self.jd_client.config.monitoring_address() { | ||
| info!("Initializing monitoring server on http://{monitoring_addr}"); | ||
| if let Err(e) = self.start_monitoring_tasks(&channel_manager, monitoring_addr) { | ||
| error!("Failed to initialize monitoring tasks: {e}"); | ||
| self.jd_client.cancellation_token.cancel(); | ||
| } | ||
| } |
There was a problem hiding this comment.
Why are we not propagating error here, in case the monitoring services doesn't spawn?
There was a problem hiding this comment.
Nice, we can also remove the cancellation token call here because we already call mark_stopped on fail state
There was a problem hiding this comment.
I did some checks and found a related issue in connect_to_bitcoin_core and I tagged you in the issue
There was a problem hiding this comment.
thanks for reporting
for now I think we should treat #679 as orthogonal and deal with it later
|
trying to expedite this PR, here's a few commit suggestions to be cherry-picked (on this specific order, otherwise won't apply) and squashed:
moreover, #685 is aligning Pool with some patterns that are being established here, and also addressing some bugs found here |
|
also needs rebasing against |
eb5e808 to
66f4587
Compare
I'll apply the same rationale here to this PR #644 for the |
no worries, your contributions are much appreciated! whenever you have time, please have a look at #685 along with the commits suggested above, it will probably bring some important insights to #644 |
|
oh oops, I guess we posted at the same time |
75e9cd7 to
215a5cd
Compare
|
I just added a tiny Rust doc change for mark_stopped so that it's consistent with the changes you made to PoolRuntime @plebhash |
bit-aloo
left a comment
There was a problem hiding this comment.
Looks good to me. Thanks for working on this.
…pestate machine Overhauls the JDC initialization sequence to align its API and behavior with PoolRuntime. - Typestate Machine: Replaces the monolithic startup logic with strict Init -> TemplateProviderReady -> UpstreamReady -> Running state transitions. - Separation of Concerns: Constructs ChannelManager and core services during bootstrap, but explicitly activates them later in start_services_inner. - Error Propagation: Ensures all startup errors cascade cleanly via Result signatures instead of failing silently or panicking. - Unblocking Bootstrap: Spawns the downstream IBD template wait loop into the background to prevent the JDC from freezing during Bitcoin Core syncs, keeping Ctrl+C functional. TcpListener::bind is preserved as a synchronous check for immediate port-in-use feedback. - Cleanups: Normalizes visibilities to pub(super), restores must_use attributes, and removes redundant mark_stopped() calls.
215a5cd to
d50d3a2
Compare
`PoolSv2::start` propagated a `PoolRuntime::<Init>::new` failure with `?`, leaving `is_alive` true and never calling `notify_waiters()`. Since `PoolSv2` is `Clone`, a concurrent holder calling `PoolSv2::shutdown` would pass the `is_alive` check and then block forever on `notified`, because the only `notify_waiters()` lives in `PoolRuntime::shutdown` — and on that path no runtime was ever built. Extract `mark_stopped()` (mirroring `JobDeclaratorClient::mark_stopped`, per bit-aloo's review on stratum-mining#633), route `PoolRuntime::shutdown` through it, and call it directly on the `new()` failure path.
`PoolSv2::start` propagated a `PoolRuntime::<Init>::new` failure with `?`, leaving `is_alive` true and never calling `notify_waiters()`. Since `PoolSv2` is `Clone`, a concurrent holder calling `PoolSv2::shutdown` would pass the `is_alive` check and then block forever on `notified`, because the only `notify_waiters()` lives in `PoolRuntime::shutdown` — and on that path no runtime was ever built. Extract `mark_stopped()` (mirroring `JobDeclaratorClient::mark_stopped`, per bit-aloo's review on stratum-mining#633), route `PoolRuntime::shutdown` through it, and call it directly on the `new()` failure path.
`PoolRuntime` startup and shutdown gaps, aligned with #633
Refactors the monolithic
startfunction inside the Pool (miner-apps/jd-client) into a structured, typestate-based state machine (JdcRuntime) to manage bootstrap, component lifecycles, and graceful shutdown.This PR also properly handles errors instead of calling
unwraporexpectFixes #526