-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #4 from antonilol/async
initial async support
- Loading branch information
Showing
11 changed files
with
441 additions
and
173 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
use bitcoincore_zmq::subscribe_single_async; | ||
use futures::executor::block_on; | ||
use futures_util::StreamExt; | ||
|
||
fn main() { | ||
let mut stream = subscribe_single_async("tcp://127.0.0.1:28332").unwrap(); | ||
|
||
// This is a small example to demonstrate subscribe_single_async, it is okay here to use | ||
// block_on, but not in production environments as this defeats the purpose of async. | ||
block_on(async { | ||
while let Some(msg) = stream.next().await { | ||
match msg { | ||
Ok(msg) => println!("Received message: {msg}"), | ||
Err(err) => println!("Error receiving message: {err}"), | ||
} | ||
} | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
use super::{new_socket_internal, subscribe_internal}; | ||
use crate::{error::Result, message::Message}; | ||
use core::{convert::Infallible, ops::ControlFlow}; | ||
use std::{sync::mpsc::channel, thread}; | ||
use zmq::Context; | ||
|
||
fn break_on_err(is_err: bool) -> ControlFlow<()> { | ||
if is_err { | ||
ControlFlow::Break(()) | ||
} else { | ||
ControlFlow::Continue(()) | ||
} | ||
} | ||
|
||
/// Subscribes to a single ZMQ endpoint and blocks the thread until [`ControlFlow::Break`] is | ||
/// returned by the callback. | ||
#[inline] | ||
pub fn subscribe_single_blocking<F, B>( | ||
endpoint: &str, | ||
callback: F, | ||
) -> Result<ControlFlow<B, Infallible>> | ||
where | ||
F: Fn(Result<Message>) -> ControlFlow<B>, | ||
{ | ||
let context = Context::new(); | ||
|
||
let socket = new_socket_internal(&context, endpoint)?; | ||
|
||
Ok(subscribe_internal(socket, callback)) | ||
} | ||
|
||
/// Subscribes to multiple ZMQ endpoints and blocks the thread until [`ControlFlow::Break`] is | ||
/// returned by the callback. | ||
#[inline] | ||
pub fn subscribe_multi_blocking<F, B>( | ||
endpoints: &[&str], | ||
callback: F, | ||
) -> Result<ControlFlow<B, Infallible>> | ||
where | ||
F: Fn(Result<Message>) -> ControlFlow<B>, | ||
{ | ||
let (tx, rx) = channel(); | ||
let context = Context::new(); | ||
|
||
for endpoint in endpoints { | ||
let tx = tx.clone(); | ||
|
||
let socket = new_socket_internal(&context, endpoint)?; | ||
|
||
thread::spawn(move || { | ||
subscribe_internal(socket, |msg| break_on_err(tx.send(msg).is_err())) | ||
}); | ||
} | ||
|
||
Ok((|| { | ||
for msg in rx { | ||
callback(msg)?; | ||
} | ||
|
||
// `tx` is dropped at the end of this function | ||
unreachable!(); | ||
})()) | ||
} |
Oops, something went wrong.