-
Notifications
You must be signed in to change notification settings - Fork 113
Introduce Runtime
object allowng to detect outer runtime context
#543
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,6 +28,7 @@ use crate::liquidity::{ | |
use crate::logger::{log_error, log_info, LdkLogger, LogLevel, LogWriter, Logger}; | ||
use crate::message_handler::NodeCustomMessageHandler; | ||
use crate::peer_store::PeerStore; | ||
use crate::runtime::Runtime; | ||
use crate::tx_broadcaster::TransactionBroadcaster; | ||
use crate::types::{ | ||
ChainMonitor, ChannelManager, DynStore, GossipSync, Graph, KeysManager, MessageRouter, | ||
|
@@ -168,6 +169,8 @@ pub enum BuildError { | |
InvalidAnnouncementAddresses, | ||
/// The provided alias is invalid. | ||
InvalidNodeAlias, | ||
/// An attempt to setup a runtime has failed. | ||
RuntimeSetupFailed, | ||
/// We failed to read data from the [`KVStore`]. | ||
/// | ||
/// [`KVStore`]: lightning::util::persist::KVStore | ||
|
@@ -205,6 +208,7 @@ impl fmt::Display for BuildError { | |
Self::InvalidAnnouncementAddresses => { | ||
write!(f, "Given announcement addresses are invalid.") | ||
}, | ||
Self::RuntimeSetupFailed => write!(f, "Failed to setup a runtime."), | ||
Self::ReadFailed => write!(f, "Failed to read from store."), | ||
Self::WriteFailed => write!(f, "Failed to write to store."), | ||
Self::StoragePathAccessFailed => write!(f, "Failed to access the given storage path."), | ||
|
@@ -236,6 +240,7 @@ pub struct NodeBuilder { | |
gossip_source_config: Option<GossipSourceConfig>, | ||
liquidity_source_config: Option<LiquiditySourceConfig>, | ||
log_writer_config: Option<LogWriterConfig>, | ||
runtime_handle: Option<tokio::runtime::Handle>, | ||
} | ||
|
||
impl NodeBuilder { | ||
|
@@ -252,16 +257,28 @@ impl NodeBuilder { | |
let gossip_source_config = None; | ||
let liquidity_source_config = None; | ||
let log_writer_config = None; | ||
let runtime_handle = None; | ||
Self { | ||
config, | ||
entropy_source_config, | ||
chain_data_source_config, | ||
gossip_source_config, | ||
liquidity_source_config, | ||
log_writer_config, | ||
runtime_handle, | ||
} | ||
} | ||
|
||
/// Configures the [`Node`] instance to (re-)use a specific `tokio` runtime. | ||
/// | ||
/// If not provided, the node will spawn its own runtime or reuse any outer runtime context it | ||
/// can detect. | ||
#[cfg_attr(feature = "uniffi", allow(dead_code))] | ||
pub fn set_runtime(&mut self, runtime_handle: tokio::runtime::Handle) -> &mut Self { | ||
self.runtime_handle = Some(runtime_handle); | ||
self | ||
} | ||
|
||
/// Configures the [`Node`] instance to source its wallet entropy from a seed file on disk. | ||
/// | ||
/// If the given file does not exist a new random seed file will be generated and | ||
|
@@ -650,6 +667,15 @@ impl NodeBuilder { | |
) -> Result<Node, BuildError> { | ||
let logger = setup_logger(&self.log_writer_config, &self.config)?; | ||
|
||
let runtime = if let Some(handle) = self.runtime_handle.as_ref() { | ||
Arc::new(Runtime::with_handle(handle.clone())) | ||
} else { | ||
Arc::new(Runtime::new().map_err(|e| { | ||
log_error!(logger, "Failed to setup tokio runtime: {}", e); | ||
BuildError::RuntimeSetupFailed | ||
})?) | ||
}; | ||
|
||
let seed_bytes = seed_bytes_from_config( | ||
&self.config, | ||
self.entropy_source_config.as_ref(), | ||
|
@@ -678,6 +704,7 @@ impl NodeBuilder { | |
self.gossip_source_config.as_ref(), | ||
self.liquidity_source_config.as_ref(), | ||
seed_bytes, | ||
runtime, | ||
logger, | ||
Arc::new(vss_store), | ||
) | ||
|
@@ -687,6 +714,15 @@ impl NodeBuilder { | |
pub fn build_with_store(&self, kv_store: Arc<DynStore>) -> Result<Node, BuildError> { | ||
let logger = setup_logger(&self.log_writer_config, &self.config)?; | ||
|
||
let runtime = if let Some(handle) = self.runtime_handle.as_ref() { | ||
Arc::new(Runtime::with_handle(handle.clone())) | ||
} else { | ||
Arc::new(Runtime::new().map_err(|e| { | ||
log_error!(logger, "Failed to setup tokio runtime: {}", e); | ||
BuildError::RuntimeSetupFailed | ||
})?) | ||
}; | ||
|
||
let seed_bytes = seed_bytes_from_config( | ||
&self.config, | ||
self.entropy_source_config.as_ref(), | ||
|
@@ -700,6 +736,7 @@ impl NodeBuilder { | |
self.gossip_source_config.as_ref(), | ||
self.liquidity_source_config.as_ref(), | ||
seed_bytes, | ||
runtime, | ||
logger, | ||
kv_store, | ||
) | ||
|
@@ -1049,7 +1086,7 @@ fn build_with_store_internal( | |
config: Arc<Config>, chain_data_source_config: Option<&ChainDataSourceConfig>, | ||
gossip_source_config: Option<&GossipSourceConfig>, | ||
liquidity_source_config: Option<&LiquiditySourceConfig>, seed_bytes: [u8; 64], | ||
logger: Arc<Logger>, kv_store: Arc<DynStore>, | ||
runtime: Arc<Runtime>, logger: Arc<Logger>, kv_store: Arc<DynStore>, | ||
) -> Result<Node, BuildError> { | ||
optionally_install_rustls_cryptoprovider(); | ||
|
||
|
@@ -1241,8 +1278,6 @@ fn build_with_store_internal( | |
}, | ||
}; | ||
|
||
let runtime = Arc::new(RwLock::new(None)); | ||
|
||
// Initialize the ChainMonitor | ||
let chain_monitor: Arc<ChainMonitor> = Arc::new(chainmonitor::ChainMonitor::new( | ||
Some(Arc::clone(&chain_source)), | ||
|
@@ -1637,6 +1672,8 @@ fn build_with_store_internal( | |
let background_tasks = Mutex::new(None); | ||
let cancellable_background_tasks = Mutex::new(None); | ||
|
||
let is_running = Arc::new(RwLock::new(false)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should really be an There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, we chose an |
||
|
||
Ok(Node { | ||
runtime, | ||
stop_sender, | ||
|
@@ -1664,6 +1701,7 @@ fn build_with_store_internal( | |
scorer, | ||
peer_store, | ||
payment_store, | ||
is_running, | ||
is_listening, | ||
node_metrics, | ||
}) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code reuse opportunity
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NACK, IMO it's much more readable to keep short blocks like this inlined, instead of having the reader jump all over the file, losing context.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't agree. I think eliminating the risk of future code changes not being applied in both places is more important than having the reader jump to a function. The function can have a descriptive name too such as
build_runtime
. I don't think it is bad for readability at all.Your argument of jumping all over the file would also apply to code that isn't necessarily duplicated. Because also in that case, the reader would have to jump. I think that would lead to long function bodies, of which there are already too many in ldk, and those absolutely do not help with readability.