Skip to content

Commit 62eef13

Browse files
author
Andrew J Westlake
committed
Added config knobs to pyo3_asyncio::tokio::main and examples for each
1 parent 0564b67 commit 62eef13

File tree

8 files changed

+364
-52
lines changed

8 files changed

+364
-52
lines changed

Cargo.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,16 @@ name = "tokio"
3232
path = "examples/tokio.rs"
3333
required-features = ["attributes", "tokio-runtime"]
3434

35+
[[example]]
36+
name = "tokio_current_thread"
37+
path = "examples/tokio_current_thread.rs"
38+
required-features = ["attributes", "tokio-runtime"]
39+
40+
[[example]]
41+
name = "tokio_multi_thread"
42+
path = "examples/tokio_multi_thread.rs"
43+
required-features = ["attributes", "tokio-runtime"]
44+
3545
[[test]]
3646
name = "test_async_std_asyncio"
3747
path = "pytests/test_async_std_asyncio.rs"

examples/async_std.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use pyo3::prelude::*;
2+
13
#[pyo3_asyncio::async_std::main]
24
async fn main() -> PyResult<()> {
35
let fut = Python::with_gil(|py| {

examples/tokio.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use pyo3::prelude::*;
2+
13
#[pyo3_asyncio::tokio::main]
24
async fn main() -> PyResult<()> {
35
let fut = Python::with_gil(|py| {

examples/tokio_current_thread.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
use pyo3::prelude::*;
2+
3+
#[pyo3_asyncio::tokio::main(flavor = "current_thread")]
4+
async fn main() -> PyResult<()> {
5+
let fut = Python::with_gil(|py| {
6+
let asyncio = py.import("asyncio")?;
7+
8+
// convert asyncio.sleep into a Rust Future
9+
pyo3_asyncio::into_future(asyncio.call_method1("sleep", (1.into_py(py),))?)
10+
})?;
11+
12+
println!("sleeping for 1s");
13+
fut.await?;
14+
println!("done");
15+
16+
Ok(())
17+
}

examples/tokio_multi_thread.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
use pyo3::prelude::*;
2+
3+
#[pyo3_asyncio::tokio::main(flavor = "multi_thread", worker_threads = 10)]
4+
async fn main() -> PyResult<()> {
5+
let fut = Python::with_gil(|py| {
6+
let asyncio = py.import("asyncio")?;
7+
8+
// convert asyncio.sleep into a Rust Future
9+
pyo3_asyncio::into_future(asyncio.call_method1("sleep", (1.into_py(py),))?)
10+
})?;
11+
12+
println!("sleeping for 1s");
13+
fut.await?;
14+
println!("done");
15+
16+
Ok(())
17+
}

pyo3-asyncio-macros/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@ edition = "2018"
88
proc-macro = true
99

1010
[dependencies]
11+
proc-macro2 = "1.0"
1112
quote = "1"
1213
syn = { version = "1", features = ["full"] }

pyo3-asyncio-macros/src/lib.rs

Lines changed: 26 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
#![deny(missing_debug_implementations, nonstandard_style)]
33
#![recursion_limit = "512"]
44

5+
mod tokio;
6+
57
use proc_macro::TokenStream;
68
use quote::{quote, quote_spanned};
79
use syn::spanned::Spanned;
@@ -47,9 +49,7 @@ pub fn async_std_main(_attr: TokenStream, item: TokenStream) -> TokenStream {
4749
#body
4850
}
4951

50-
use pyo3::prelude::*;
51-
52-
Python::with_gil(|py| {
52+
pyo3::Python::with_gil(|py| {
5353
pyo3_asyncio::with_runtime(py, || {
5454
pyo3_asyncio::async_std::run_until_complete(py, main())?;
5555

@@ -61,70 +61,44 @@ pub fn async_std_main(_attr: TokenStream, item: TokenStream) -> TokenStream {
6161
.unwrap();
6262
});
6363
}
64-
6564
};
6665

6766
result.into()
6867
}
6968

7069
/// Enables an async main function that uses the tokio runtime.
7170
///
71+
/// # Arguments
72+
/// * `flavor` - selects the type of tokio runtime ["multi_thread", "current_thread"]
73+
/// * `worker_threads` - number of worker threads, defaults to the number of CPUs on the system
74+
///
7275
/// # Examples
7376
///
77+
/// Default configuration:
7478
/// ```ignore
7579
/// #[pyo3_asyncio::tokio::main]
7680
/// async fn main() -> PyResult<()> {
7781
/// Ok(())
7882
/// }
7983
/// ```
84+
///
85+
/// Current-thread scheduler:
86+
/// ```ignore
87+
/// #[pyo3_asyncio::tokio::main(flavor = "current_thread")]
88+
/// async fn main() -> PyResult<()> {
89+
/// Ok(())
90+
/// }
91+
/// ```
92+
///
93+
/// Multi-thread scheduler with custom worker thread count:
94+
/// ```ignore
95+
/// #[pyo3_asyncio::tokio::main(flavor = "multi_thread", worker_threads = 10)]
96+
/// async fn main() -> PyResult<()> {
97+
/// Ok(())
98+
/// }
99+
/// ```
80100
#[cfg(not(test))] // NOTE: exporting main breaks tests, we should file an issue.
81101
#[proc_macro_attribute]
82-
pub fn tokio_main(_attr: TokenStream, item: TokenStream) -> TokenStream {
83-
let input = syn::parse_macro_input!(item as syn::ItemFn);
84-
85-
let ret = &input.sig.output;
86-
let inputs = &input.sig.inputs;
87-
let name = &input.sig.ident;
88-
let body = &input.block;
89-
let attrs = &input.attrs;
90-
let vis = &input.vis;
91-
92-
if name != "main" {
93-
return TokenStream::from(quote_spanned! { name.span() =>
94-
compile_error!("only the main function can be tagged with #[async_std::main]"),
95-
});
96-
}
97-
98-
if input.sig.asyncness.is_none() {
99-
return TokenStream::from(quote_spanned! { input.span() =>
100-
compile_error!("the async keyword is missing from the function declaration"),
101-
});
102-
}
103-
104-
let result = quote! {
105-
#vis fn main() {
106-
#(#attrs)*
107-
async fn main(#inputs) #ret {
108-
#body
109-
}
110-
111-
use pyo3::prelude::*;
112-
113-
pyo3_asyncio::tokio::init_multi_thread();
114-
115-
Python::with_gil(|py| {
116-
pyo3_asyncio::with_runtime(py, || {
117-
pyo3_asyncio::tokio::run_until_complete(py, main())?;
118-
119-
Ok(())
120-
})
121-
.map_err(|e| {
122-
e.print_and_set_sys_last_vars(py);
123-
})
124-
.unwrap();
125-
});
126-
}
127-
};
128-
129-
result.into()
102+
pub fn tokio_main(args: TokenStream, item: TokenStream) -> TokenStream {
103+
tokio::main(args, item, true)
130104
}

0 commit comments

Comments
 (0)