mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-02-22 14:42:40 +01:00
cln-plugin: Handle --help invocations better
We now have ternary outcomes for `Builder.configure()` and `Builder.start()`: - Ok(Some(p)) means we were configured correctly, and can continue with our work normally - Ok(None) means that `lightningd` was invoked with `--help`, we weren't configured (which is not an error since the `lightningd` just implicitly told us to shut down) and user code should clean up and exit as well - Err(e) something went wrong, user code may report an error and exit.
This commit is contained in:
parent
c36cef08bc
commit
b359a24772
3 changed files with 41 additions and 13 deletions
|
@ -6,7 +6,7 @@ use cln_plugin::{options, Builder, Error, Plugin};
|
||||||
use tokio;
|
use tokio;
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<(), anyhow::Error> {
|
async fn main() -> Result<(), anyhow::Error> {
|
||||||
let plugin = Builder::new((), tokio::io::stdin(), tokio::io::stdout())
|
if let Some(plugin) = Builder::new((), tokio::io::stdin(), tokio::io::stdout())
|
||||||
.option(options::ConfigOption::new(
|
.option(options::ConfigOption::new(
|
||||||
"test-option",
|
"test-option",
|
||||||
options::Value::Integer(42),
|
options::Value::Integer(42),
|
||||||
|
@ -16,8 +16,12 @@ async fn main() -> Result<(), anyhow::Error> {
|
||||||
.subscribe("connect", connect_handler)
|
.subscribe("connect", connect_handler)
|
||||||
.hook("peer_connected", peer_connected_handler)
|
.hook("peer_connected", peer_connected_handler)
|
||||||
.start()
|
.start()
|
||||||
.await?;
|
.await?
|
||||||
plugin.join().await
|
{
|
||||||
|
plugin.join().await
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn testmethod(_p: Plugin<()>, _v: serde_json::Value) -> Result<serde_json::Value, Error> {
|
async fn testmethod(_p: Plugin<()>, _v: serde_json::Value) -> Result<serde_json::Value, Error> {
|
||||||
|
@ -29,7 +33,10 @@ async fn connect_handler(_p: Plugin<()>, v: serde_json::Value) -> Result<(), Err
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn peer_connected_handler(_p: Plugin<()>, v: serde_json::Value) -> Result<serde_json::Value, Error> {
|
async fn peer_connected_handler(
|
||||||
|
_p: Plugin<()>,
|
||||||
|
v: serde_json::Value,
|
||||||
|
) -> Result<serde_json::Value, Error> {
|
||||||
log::info!("Got a connect hook call: {}", v);
|
log::info!("Got a connect hook call: {}", v);
|
||||||
Ok(json!({"result": "continue"}))
|
Ok(json!({"result": "continue"}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,19 +28,25 @@ async fn main() -> Result<()> {
|
||||||
ca_cert,
|
ca_cert,
|
||||||
};
|
};
|
||||||
|
|
||||||
let plugin = Builder::new(state.clone(), tokio::io::stdin(), tokio::io::stdout())
|
let plugin = match Builder::new(state.clone(), tokio::io::stdin(), tokio::io::stdout())
|
||||||
.option(options::ConfigOption::new(
|
.option(options::ConfigOption::new(
|
||||||
"grpc-port",
|
"grpc-port",
|
||||||
options::Value::Integer(-1),
|
options::Value::Integer(-1),
|
||||||
"Which port should the grpc plugin listen for incoming connections?",
|
"Which port should the grpc plugin listen for incoming connections?",
|
||||||
))
|
))
|
||||||
.configure()
|
.configure()
|
||||||
.await?;
|
.await?
|
||||||
|
{
|
||||||
|
Some(p) => p,
|
||||||
|
None => return Ok(()),
|
||||||
|
};
|
||||||
|
|
||||||
let bind_port = match plugin.option("grpc-port") {
|
let bind_port = match plugin.option("grpc-port") {
|
||||||
Some(options::Value::Integer(-1)) => {
|
Some(options::Value::Integer(-1)) => {
|
||||||
log::info!("`grpc-port` option is not configured, exiting.");
|
log::info!("`grpc-port` option is not configured, exiting.");
|
||||||
plugin.disable("`grpc-port` option is not configured.").await?;
|
plugin
|
||||||
|
.disable("`grpc-port` option is not configured.")
|
||||||
|
.await?;
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
Some(options::Value::Integer(i)) => i,
|
Some(options::Value::Integer(i)) => i,
|
||||||
|
|
|
@ -139,7 +139,13 @@ where
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn configure(mut self) -> Result<ConfiguredPlugin<S, I, O>, anyhow::Error> {
|
/// Communicate with `lightningd` to tell it about our options,
|
||||||
|
/// RPC methods and subscribe to hooks, and then process the
|
||||||
|
/// initialization, configuring the plugin.
|
||||||
|
///
|
||||||
|
/// Returns `None` if we were invoked with `--help` and thus
|
||||||
|
/// should exit after this handshake
|
||||||
|
pub async fn configure(mut self) -> Result<Option<ConfiguredPlugin<S, I, O>>, anyhow::Error> {
|
||||||
let mut input = FramedRead::new(self.input.take().unwrap(), JsonRpcCodec::default());
|
let mut input = FramedRead::new(self.input.take().unwrap(), JsonRpcCodec::default());
|
||||||
|
|
||||||
// Sadly we need to wrap the output in a mutex in order to
|
// Sadly we need to wrap the output in a mutex in order to
|
||||||
|
@ -189,7 +195,7 @@ where
|
||||||
// If we are being called with --help we will get
|
// If we are being called with --help we will get
|
||||||
// disconnected here. That's expected, so don't
|
// disconnected here. That's expected, so don't
|
||||||
// complain about it.
|
// complain about it.
|
||||||
0
|
return Ok(None);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -213,7 +219,7 @@ where
|
||||||
|
|
||||||
// Leave the `init` reply pending, so we can disable based on
|
// Leave the `init` reply pending, so we can disable based on
|
||||||
// the options if required.
|
// the options if required.
|
||||||
Ok(ConfiguredPlugin {
|
Ok(Some(ConfiguredPlugin {
|
||||||
// The JSON-RPC `id` field so we can reply correctly.
|
// The JSON-RPC `id` field so we can reply correctly.
|
||||||
init_id,
|
init_id,
|
||||||
input,
|
input,
|
||||||
|
@ -228,7 +234,7 @@ where
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
plugin,
|
plugin,
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Build and start the plugin loop. This performs the handshake
|
/// Build and start the plugin loop. This performs the handshake
|
||||||
|
@ -236,8 +242,17 @@ where
|
||||||
/// Core Lightning and dispatches them to the handlers. It only
|
/// Core Lightning and dispatches them to the handlers. It only
|
||||||
/// returns after completing the handshake to ensure that the
|
/// returns after completing the handshake to ensure that the
|
||||||
/// configuration and initialization was successfull.
|
/// configuration and initialization was successfull.
|
||||||
pub async fn start(self) -> Result<Plugin<S>, anyhow::Error> {
|
///
|
||||||
self.configure().await?.start().await
|
/// If `lightningd` was called with `--help` we won't get a
|
||||||
|
/// `Plugin` instance and return `None` instead. This signals that
|
||||||
|
/// we should exit, and not continue running. `start()` returns in
|
||||||
|
/// order to allow user code to perform cleanup if necessary.
|
||||||
|
pub async fn start(self) -> Result<Option<Plugin<S>>, anyhow::Error> {
|
||||||
|
if let Some(cp) = self.configure().await? {
|
||||||
|
Ok(Some(cp.start().await?))
|
||||||
|
} else {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_get_manifest(
|
fn handle_get_manifest(
|
||||||
|
|
Loading…
Add table
Reference in a new issue