mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-09-07 00:00:08 +02:00
## Motivation The `futures` crate's [`compat` module][futures-compat] provides interoperability between `futures` 0.1 and `std::future` _future types_ (e.g. implementing `std::future::Future` for a type that implements the `futures` 0.1 `Future` trait). However, this on its own is insufficient to run code written against `tokio` 0.1 on a `tokio` 0.2 runtime, if that code also relies on `tokio`'s runtime services. If legacy tasks are executed that rely on `tokio::timer`, perform IO using `tokio`'s reactor, or call `tokio::spawn`, those API calls will fail unless there is also a runtime compatibility layer. ## Solution As proposed in #1549, this branch introduces a new `tokio-compat` crate, with implementations of the thread pool and current-thread runtimes that are capable of running both tokio 0.1 and tokio 0.2 tasks. The compat runtime creates a background thread that runs a `tokio` 0.1 timer and reactor, and sets itself as the `tokio` 0.1 executor as well as the default 0.2 executor. This allows 0.1 futures that use 0.1 timer, reactor, and executor APIs may run alongside `std::future` tasks on the 0.2 runtime. ### Examples Spawning both `tokio` 0.1 and `tokio` 0.2 futures: ```rust use futures_01::future::lazy; tokio_compat::run(lazy(|| { // spawn a `futures` 0.1 future using the `spawn` function from the // `tokio` 0.1 crate: tokio_01::spawn(lazy(|| { println!("hello from tokio 0.1!"); Ok(()) })); // spawn an `async` block future on the same runtime using `tokio` // 0.2's `spawn`: tokio_02::spawn(async { println!("hello from tokio 0.2!"); }); Ok(()) })) ``` Futures on the compat runtime can use `timer` APIs from both 0.1 and 0.2 versions of `tokio`: ```rust use std::time::{Duration, Instant}; use futures_01::future::lazy; use tokio_compat::prelude::*; tokio_compat::run_03(async { // Wait for a `tokio` 0.1 `Delay`... let when = Instant::now() + Duration::from_millis(10); tokio_01::timer::Delay::new(when) // convert the delay future into a `std::future` that we can `await`. .compat() .await .expect("tokio 0.1 timer should work!"); println!("10 ms have elapsed"); // Wait for a `tokio` 0.2 `Delay`... let when = Instant::now() + Duration::from_millis(20); tokio_02::timer::delay(when).await; println!("20 ms have elapsed"); }); ``` ## Future Work This is just an initial implementation of a `tokio-compat` crate; there are more compatibility layers we'll want to provide before that crate is complete. For example, we should also provide compatibility between `tokio` 0.2's `AsyncRead` and `AsyncWrite` traits and the `futures` 0.1 and `futures` 0.3 versions of those traits. In #1549, @carllerche also suggests that the `compat` crate provide reimplementations of APIs that were removed from `tokio` 0.2 proper, such as the `tcp::Incoming` future. Additionally, there is likely extra work required to get the `tokio-threadpool` 0.1 `blocking` APIs to work on the compat runtime. This will be addressed in a follow-up PR. Fixes: #1605 Fixes: #1552 Refs: #1549 [futures-compat]: https://rust-lang-nursery.github.io/futures-api-docs/0.3.0-alpha.19/futures/compat/index.html
89 lines
2.6 KiB
Markdown
89 lines
2.6 KiB
Markdown
# Tokio Compat
|
|
|
|
Compatibility layers between `tokio` 0.2 and legacy versions.
|
|
|
|
[![Crates.io][crates-badge]][crates-url]
|
|
[![MIT licensed][mit-badge]][mit-url]
|
|
[![Build Status][azure-badge]][azure-url]
|
|
[![Gitter chat][gitter-badge]][gitter-url]
|
|
|
|
[crates-badge]: https://img.shields.io/crates/v/tokio-compat.svg
|
|
[crates-url]: https://crates.io/crates/tokio-compat
|
|
[mit-badge]: https://img.shields.io/badge/license-MIT-blue.svg
|
|
[mit-url]: LICENSE
|
|
[azure-badge]: https://dev.azure.com/tokio-rs/Tokio/_apis/build/status/tokio-rs.tokio?branchName=master
|
|
[azure-url]: https://dev.azure.com/tokio-rs/Tokio/_build/latest?definitionId=1&branchName=master
|
|
[gitter-badge]: https://img.shields.io/gitter/room/tokio-rs/tokio.svg
|
|
[gitter-url]: https://gitter.im/tokio-rs/tokio
|
|
|
|
[Website](https://tokio.rs) |
|
|
[Guides](https://tokio.rs/docs/) |
|
|
[API Docs](https://docs.rs/tokio-compat/0.1.0-alpha.1/tokio-compat) |
|
|
[Chat](https://gitter.im/tokio-rs/tokio)
|
|
|
|
## Overview
|
|
|
|
This crate provides compatibility runtimes that allow running both `futures` 0.1
|
|
futures that use `tokio` 0.1 runtime services _and_ `std::future` futures that
|
|
use `tokio` 0.2 runtime services.
|
|
|
|
### Examples
|
|
|
|
Spawning both `tokio` 0.1 and `tokio` 0.2 futures:
|
|
|
|
```rust
|
|
use futures_01::future::lazy;
|
|
|
|
tokio_compat::run(lazy(|| {
|
|
// spawn a `futures` 0.1 future using the `spawn` function from the
|
|
// `tokio` 0.1 crate:
|
|
tokio_01::spawn(lazy(|| {
|
|
println!("hello from tokio 0.1!");
|
|
Ok(())
|
|
}));
|
|
|
|
// spawn an `async` block future on the same runtime using `tokio`
|
|
// 0.2's `spawn`:
|
|
tokio_02::spawn(async {
|
|
println!("hello from tokio 0.2!");
|
|
});
|
|
|
|
Ok(())
|
|
}))
|
|
```
|
|
|
|
Futures on the compat runtime can use `timer` APIs from both 0.1 and 0.2
|
|
versions of `tokio`:
|
|
|
|
```rust
|
|
use std::time::{Duration, Instant};
|
|
use futures_01::future::lazy;
|
|
use tokio_compat::prelude::*;
|
|
|
|
tokio_compat::run_std(async {
|
|
// Wait for a `tokio` 0.1 `Delay`...
|
|
let when = Instant::now() + Duration::from_millis(10);
|
|
tokio_01::timer::Delay::new(when)
|
|
// convert the delay future into a `std::future` that we can `await`.
|
|
.compat()
|
|
.await
|
|
.expect("tokio 0.1 timer should work!");
|
|
println!("10 ms have elapsed");
|
|
|
|
// Wait for a `tokio` 0.2 `Delay`...
|
|
let when = Instant::now() + Duration::from_millis(20);
|
|
tokio_02::timer::delay(when).await;
|
|
println!("20 ms have elapsed");
|
|
});
|
|
```
|
|
|
|
## License
|
|
|
|
This project is licensed under the [MIT license](LICENSE).
|
|
|
|
### Contribution
|
|
|
|
Unless you explicitly state otherwise, any contribution intentionally submitted
|
|
for inclusion in Tokio by you, shall be licensed as MIT, without any additional
|
|
terms or conditions.
|