Merge branch 'eta/182' into 'main'
Improve the layout of crate exports; add runtime convenience functions See merge request tpo/core/arti!235
This commit is contained in:
commit
b4761f8cfd
|
@ -23,6 +23,10 @@ use std::sync::{Arc, Mutex, Weak};
|
|||
use std::time::Duration;
|
||||
|
||||
use crate::{Error, Result};
|
||||
#[cfg(feature = "async-std")]
|
||||
use tor_rtcompat::async_std::AsyncStdRuntime;
|
||||
#[cfg(feature = "tokio")]
|
||||
use tor_rtcompat::tokio::TokioRuntimeHandle;
|
||||
use tracing::{debug, error, info, warn};
|
||||
|
||||
/// An active client session on the Tor network.
|
||||
|
@ -166,10 +170,49 @@ impl ConnectPrefs {
|
|||
// TODO: Add some way to be IPFlexible, and require exit to support both.
|
||||
}
|
||||
|
||||
impl<R: Runtime> TorClient<R> {
|
||||
/// Bootstrap a network connection configured by `dir_cfg` and `circ_cfg`.
|
||||
#[cfg(feature = "tokio")]
|
||||
impl TorClient<TokioRuntimeHandle> {
|
||||
/// Bootstrap a connection to the Tor network, using the current Tokio runtime.
|
||||
///
|
||||
/// Return a client once there is enough directory material to
|
||||
/// Returns a client once there is enough directory material to
|
||||
/// connect safely over the Tor network.
|
||||
///
|
||||
/// This is a convenience wrapper around [`TorClient::bootstrap`].
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if called outside of the context of a Tokio runtime.
|
||||
pub async fn bootstrap_with_tokio(
|
||||
config: TorClientConfig,
|
||||
) -> Result<TorClient<TokioRuntimeHandle>> {
|
||||
let rt = tor_rtcompat::tokio::current_runtime().expect("called outside of Tokio runtime");
|
||||
Self::bootstrap(rt, config).await
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "async-std")]
|
||||
impl TorClient<AsyncStdRuntime> {
|
||||
/// Bootstrap a connection to the Tor network, using the current async-std runtime.
|
||||
///
|
||||
/// Returns a client once there is enough directory material to
|
||||
/// connect safely over the Tor network.
|
||||
///
|
||||
/// This is a convenience wrapper around [`TorClient::bootstrap`].
|
||||
pub async fn bootstrap_with_async_std(
|
||||
config: TorClientConfig,
|
||||
) -> Result<TorClient<AsyncStdRuntime>> {
|
||||
// FIXME(eta): not actually possible for this to fail
|
||||
let rt =
|
||||
tor_rtcompat::async_std::current_runtime().expect("failed to get async-std runtime");
|
||||
Self::bootstrap(rt, config).await
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: Runtime> TorClient<R> {
|
||||
/// Bootstrap a connection to the Tor network, using the provided `config` and `runtime` (a
|
||||
/// [`tor_rtcompat`] [`Runtime`](tor_rtcompat::Runtime)).
|
||||
///
|
||||
/// Returns a client once there is enough directory material to
|
||||
/// connect safely over the Tor network.
|
||||
pub async fn bootstrap(runtime: R, config: TorClientConfig) -> Result<TorClient<R>> {
|
||||
let circ_cfg = config.get_circmgr_config()?;
|
||||
|
|
|
@ -8,9 +8,7 @@ use std::collections::HashMap;
|
|||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::time::Duration;
|
||||
use tor_config::CfgPath;
|
||||
|
||||
pub use tor_config::ConfigBuildError;
|
||||
pub use tor_config::{CfgPath, ConfigBuildError};
|
||||
|
||||
/// Types for configuring how Tor circuits are built.
|
||||
pub mod circ {
|
||||
|
|
|
@ -182,7 +182,7 @@ pub use client::{ConnectPrefs, TorClient};
|
|||
pub use config::TorClientConfig;
|
||||
|
||||
pub use tor_circmgr::IsolationToken;
|
||||
pub use tor_proto::stream::DataStream;
|
||||
pub use tor_proto::stream::{DataReader, DataStream, DataWriter};
|
||||
|
||||
mod err;
|
||||
pub use err::Error;
|
||||
|
|
|
@ -14,7 +14,7 @@ mod params;
|
|||
mod raw;
|
||||
mod resolve;
|
||||
|
||||
pub use data::DataStream;
|
||||
pub use data::{DataReader, DataStream, DataWriter};
|
||||
pub use params::StreamParameters;
|
||||
pub use raw::StreamReader;
|
||||
pub use resolve::ResolveStream;
|
||||
|
|
|
@ -74,6 +74,12 @@ use tor_cell::relaycell::msg::{Data, RelayMsg};
|
|||
/// data has actually been sent, you need to make sure that
|
||||
/// [`AsyncWrite::poll_flush`] runs to completion: probably via
|
||||
/// [`AsyncWriteExt::flush`](futures::io::AsyncWriteExt::flush).
|
||||
///
|
||||
/// # Splitting the type
|
||||
///
|
||||
/// This type is internally composed of a [`DataReader`] and a [`DataWriter`]; the
|
||||
/// `DataStream::split` method can be used to split it into those two parts, for more
|
||||
/// convenient usage with e.g. stream combinators.
|
||||
// # Semver note
|
||||
//
|
||||
// Note that this type is re-exported as a part of the public API of
|
||||
|
@ -86,11 +92,22 @@ pub struct DataStream {
|
|||
r: DataReader,
|
||||
}
|
||||
|
||||
/// Wrapper for the Write part of a DataStream.
|
||||
/// The write half of a [`DataStream`], implementing [`futures::io::AsyncWrite`].
|
||||
///
|
||||
/// Note that this implementation writes Tor cells lazily, so it is
|
||||
/// essential to flush the stream when you need the data to be sent
|
||||
/// out right away.
|
||||
/// See the [`DataStream`] docs for more information. In particular, note
|
||||
/// that this writer requires `poll_flush` to complete in order to guarantee that
|
||||
/// all data has been written.
|
||||
///
|
||||
/// # Usage with Tokio
|
||||
///
|
||||
/// If the `tokio` crate feature is enabled, this type also implements
|
||||
/// [`tokio::io::AsyncWrite`](tokio_crate::io::AsyncWrite) for easier integration
|
||||
/// with code that expects that trait.
|
||||
// # Semver note
|
||||
//
|
||||
// Note that this type is re-exported as a part of the public API of
|
||||
// the `arti-client` crate. Any changes to its API here in
|
||||
// `tor-proto` need to be reflected above.
|
||||
pub struct DataWriter {
|
||||
/// Internal state for this writer
|
||||
///
|
||||
|
@ -100,7 +117,21 @@ pub struct DataWriter {
|
|||
state: Option<DataWriterState>,
|
||||
}
|
||||
|
||||
/// Wrapper for the Read part of a DataStream
|
||||
/// The read half of a [`DataStream`], implementing [`futures::io::AsyncRead`].
|
||||
///
|
||||
/// See the [`DataStream`] docs for more information.
|
||||
///
|
||||
/// # Usage with Tokio
|
||||
///
|
||||
/// If the `tokio` crate feature is enabled, this type also implements
|
||||
/// [`tokio::io::AsyncRead`](tokio_crate::io::AsyncRead) for easier integration
|
||||
/// with code that expects that trait.
|
||||
//
|
||||
// # Semver note
|
||||
//
|
||||
// Note that this type is re-exported as a part of the public API of
|
||||
// the `arti-client` crate. Any changes to its API here in
|
||||
// `tor-proto` need to be reflected above.
|
||||
pub struct DataReader {
|
||||
/// Internal state for this reader.
|
||||
///
|
||||
|
|
|
@ -1,20 +1,23 @@
|
|||
//! Entry points for use with async_std runtimes.
|
||||
pub use crate::impls::async_std::create_runtime as create_async_std_runtime;
|
||||
use crate::{Runtime, SpawnBlocking};
|
||||
use crate::SpawnBlocking;
|
||||
|
||||
/// Return a new async-std-based [`Runtime`].
|
||||
/// A [`Runtime`](crate::Runtime) powered by async-std.
|
||||
pub use async_executors::AsyncStd as AsyncStdRuntime;
|
||||
|
||||
/// Return a new async-std-based [`Runtime`](crate::Runtime).
|
||||
///
|
||||
/// Generally you should call this function only once, and then use
|
||||
/// [`Clone::clone()`] to create additional references to that
|
||||
/// runtime.
|
||||
|
||||
pub fn create_runtime() -> std::io::Result<impl Runtime> {
|
||||
pub fn create_runtime() -> std::io::Result<AsyncStdRuntime> {
|
||||
Ok(create_async_std_runtime())
|
||||
}
|
||||
|
||||
/// Try to return an instance of the currently running async_std
|
||||
/// [`Runtime`].
|
||||
pub fn current_runtime() -> std::io::Result<impl Runtime> {
|
||||
/// [`Runtime`](crate::Runtime).
|
||||
pub fn current_runtime() -> std::io::Result<AsyncStdRuntime> {
|
||||
// In async_std, the runtime is a global singleton.
|
||||
create_runtime()
|
||||
}
|
||||
|
@ -22,7 +25,7 @@ pub fn current_runtime() -> std::io::Result<impl Runtime> {
|
|||
/// Run a test function using a freshly created async_std runtime.
|
||||
pub fn test_with_runtime<P, F, O>(func: P) -> O
|
||||
where
|
||||
P: FnOnce(async_executors::AsyncStd) -> F,
|
||||
P: FnOnce(AsyncStdRuntime) -> F,
|
||||
F: futures::Future<Output = O>,
|
||||
{
|
||||
let runtime = create_async_std_runtime();
|
||||
|
|
|
@ -32,7 +32,7 @@ pub fn create_runtime() -> std::io::Result<impl Runtime> {
|
|||
///
|
||||
/// Once you have a runtime returned by this function, you should
|
||||
/// just create more handles to it via [`Clone`].
|
||||
pub fn current_runtime() -> std::io::Result<impl Runtime> {
|
||||
pub fn current_runtime() -> std::io::Result<TokioRuntimeHandle> {
|
||||
let handle = tokio_crate::runtime::Handle::try_current()
|
||||
.map_err(|e| IoError::new(ErrorKind::Other, e))?;
|
||||
Ok(TokioRuntimeHandle::new(handle))
|
||||
|
|
Loading…
Reference in New Issue